<commit_before>/**
 * @depends App.js
 * @depends Shader.js
 * @depends Attribute.js
 * @depends Uniform.js
 */

var ShaderProgram = new Class({
    initialize: function() {
    },

    program: null,
    shaders: {},
    shaderIds: [],
    uniforms: {},
    attributes: {},
    needRecompile: true,

    addShader: function(shaderId) {
        var shader = new Shader(shaderId);
        this.shaders[shaderId] = shader;
        this.shaderIds.push(shaderId);
        this.needRecompile = true;
    },

    removeShader: function(shaderId) {
        for (var i = 0; i < this.shaderIds.length; i++) {
            if (this.shaderIds[i] == shaderId) {
                delete this.shaderIds[i];
            }
        }
        delete this.shaders[shaderId];
        this.needRecompile = true;
    },

    createProgram: function() {
        this.program = gl.createProgram();
    },

    deleteProgram: function() {
        gl.deleteProgram(this.program);
    },

    attachShaders: function() {
        for (var i = 0; i < this.shaderIds.length; i++) {
            var shader = this.shaders[this.shaderIds[i]];
            gl.attachShader(this.program, shader.getShader());
        }
    },

    getAttributes: function() {
        var numAttributes = gl.getProgramParameter(this.program,
                                                   gl.ACTIVE_ATTRIBUTES);
        console.log('Program %i has %i active attributes', this.program,
                    numAttributes);
        for (var i = 0; i < numAttributes; i++) {
            var attributeInfo = gl.getActiveAttrib(this.program, i);
            var attribute = new Attribute(attributeInfo, this.program);
            this.attributes[attribute.name] = attribute;
            console.log('Attribute %i: %s', i, attribute.name);
        }
    },

    getUniforms: function() {
        var numUniforms = gl.getProgramParameter(this.program,
                                                 gl.ACTIVE_UNIFORMS);
        console.log('Program %i has %i active uniforms', this.program,
                    numUniforms);
        for (var i = 0; i < numUniforms; i++) {
            var uniformInfo = gl.getActiveUniform(this.program, i);
            var uniform = new Uniform(uniformInfo, this.program);
            this.uniforms[uniform.name] = uniform;
            console.log('Uniform %i: %s', i, uniform.name);
        }
    },

    linkProgram: function() {
        gl.linkProgram(this.program);
        if (!gl.getProgramParameter(this.program, gl.LINK_STATUS)) {
            console.error('Could not link shader program, %i', this.program);
            return (false);
        }
        return (true);
    },

    useProgram: function() {
        gl.useProgram(this.program);
    },

    use: function() {
        if (this.needRecompile) {
            if (this.program !== null) {
                this.deleteProgram();
            }
            this.createProgram();
            this.attachShaders();
            this.linkProgram();
            this.getAttributes();
            this.getUniforms();
            this.needRecompile = false;
        }
        this.useProgram();
    },

    getUniform: function(name) {
        return (this.uniforms[name]);
    },

    getAttribute: function(name) {
        return (this.attributes[name]);
    }
});
<commit_msg>Add setUniform/setAttribute functions as shortcuts to getUniform(name).setValue(value)<commit_after>/**
 * @depends App.js
 * @depends Shader.js
 * @depends Attribute.js
 * @depends Uniform.js
 */

var ShaderProgram = new Class({
    initialize: function() {
    },

    program: null,
    shaders: {},
    shaderIds: [],
    uniforms: {},
    attributes: {},
    needRecompile: true,

    addShader: function(shaderId) {
        var shader = new Shader(shaderId);
        this.shaders[shaderId] = shader;
        this.shaderIds.push(shaderId);
        this.needRecompile = true;
    },

    removeShader: function(shaderId) {
        for (var i = 0; i < this.shaderIds.length; i++) {
            if (this.shaderIds[i] == shaderId) {
                delete this.shaderIds[i];
            }
        }
        delete this.shaders[shaderId];
        this.needRecompile = true;
    },

    createProgram: function() {
        this.program = gl.createProgram();
    },

    deleteProgram: function() {
        gl.deleteProgram(this.program);
    },

    attachShaders: function() {
        for (var i = 0; i < this.shaderIds.length; i++) {
            var shader = this.shaders[this.shaderIds[i]];
            gl.attachShader(this.program, shader.getShader());
        }
    },

    getAttributes: function() {
        var numAttributes = gl.getProgramParameter(this.program,
                                                   gl.ACTIVE_ATTRIBUTES);
        console.log('Program %i has %i active attributes', this.program,
                    numAttributes);
        for (var i = 0; i < numAttributes; i++) {
            var attributeInfo = gl.getActiveAttrib(this.program, i);
            var attribute = new Attribute(attributeInfo, this.program);
            this.attributes[attribute.name] = attribute;
            console.log('Attribute %i: %s', i, attribute.name);
        }
    },

    getUniforms: function() {
        var numUniforms = gl.getProgramParameter(this.program,
                                                 gl.ACTIVE_UNIFORMS);
        console.log('Program %i has %i active uniforms', this.program,
                    numUniforms);
        for (var i = 0; i < numUniforms; i++) {
            var uniformInfo = gl.getActiveUniform(this.program, i);
            var uniform = new Uniform(uniformInfo, this.program);
            this.uniforms[uniform.name] = uniform;
            console.log('Uniform %i: %s', i, uniform.name);
        }
    },

    linkProgram: function() {
        gl.linkProgram(this.program);
        if (!gl.getProgramParameter(this.program, gl.LINK_STATUS)) {
            console.error('Could not link shader program, %i', this.program);
            return (false);
        }
        return (true);
    },

    useProgram: function() {
        gl.useProgram(this.program);
    },

    use: function() {
        if (this.needRecompile) {
            if (this.program !== null) {
                this.deleteProgram();
            }
            this.createProgram();
            this.attachShaders();
            this.linkProgram();
            this.getAttributes();
            this.getUniforms();
            this.needRecompile = false;
        }
        this.useProgram();
    },

    getUniform: function(name) {
        return (this.uniforms[name]);
    },

    setUniform: function(name, value) {
        this.uniforms[name].setValue(value);
    },

    getAttribute: function(name) {
        return (this.attributes[name]);
    },

    setAttribute: function(name, value) {
        this.attributes[name].setValue(value);
    }
});
<|endoftext|>


<commit_before>import React from 'react';

const baseURL = 'https://www.kicktraq.com/projects';

const charts = [
  'dailychart',
  'dailypledges',
  'dailybackers',
  'dailycomments',
  'exp-cone',
]

export default function({ project, updateSeed }) {
  return (

      {charts.map(name => (
        <img src={`${baseURL}/${project}/${name}.png?updateSeed=${updateSeed}`} key={name}/>
      ))}

  );
}
<commit_msg>Link to KickTraq<commit_after>import React from 'react';

const baseURL = 'https://www.kicktraq.com/projects';

const charts = [
  'dailychart',
  'dailypledges',
  'dailybackers',
  'dailycomments',
  'exp-cone',
]

export default function({ project, updateSeed }) {
  return (

      {charts.map(name => (
        <a href={`${baseURL}/${project}`} target="_blank">
          <img src={`${baseURL}/${project}/${name}.png?updateSeed=${updateSeed}`} key={name}/>

      ))}

  );
}
<|endoftext|>


<commit_before>angular.module('demoModule', ['LocalStorageModule'])
.config(['localStorageServiceProvider', function(localStorageServiceProvider){
  localStorageServiceProvider.setPrefix('demoPrefix');
  // localStorageServiceProvider.setStorageCookieDomain('example.com');
  // localStorageServiceProvider.setStorageType('sessionStorage');
}])
.controller('DemoCtrl', [
  '$scope',
  'localStorageService',
  function($scope, localStorageService) {
    // Start fresh
    localStorageService.clearAll();

    $scope.$watch('localStorageDemo', function(value){
      localStorageService.set('localStorageDemo',value);
      $scope.localStorageDemoValue = localStorageService.get('localStorageDemo');
    });

    $scope.storageType = 'Local storage';

    if (localStorageService.getStorageType().indexOf('session') >= 0) {
      $scope.storageType = 'Session storage'
    }

    if (!localStorageService.isSupported) {
      $scope.storageType = 'Cookie';
    }
  }
]);<commit_msg>Do not flush data on page load<commit_after>angular.module('demoModule', ['LocalStorageModule'])
.config(['localStorageServiceProvider', function(localStorageServiceProvider){
  localStorageServiceProvider.setPrefix('demoPrefix');
  // localStorageServiceProvider.setStorageCookieDomain('example.com');
  // localStorageServiceProvider.setStorageType('sessionStorage');
}])
.controller('DemoCtrl', [
  '$scope',
  'localStorageService',
  function($scope, localStorageService) {

    $scope.$watch('localStorageDemo', function(value){
      localStorageService.set('localStorageDemo',value);
      $scope.localStorageDemoValue = localStorageService.get('localStorageDemo');
    });

    $scope.storageType = 'Local storage';

    if (localStorageService.getStorageType().indexOf('session') >= 0) {
      $scope.storageType = 'Session storage';
    }

    if (!localStorageService.isSupported) {
      $scope.storageType = 'Cookie';
    }
  }
]);<|endoftext|>


<commit_before>import React, { Component } from 'react';
import firebase from 'firebase';
import { Link } from 'react-router'
import {List, ListItem} from 'material-ui/List';
import {GridList, GridTile} from 'material-ui/GridList';
import FloatingActionButton from 'material-ui/FloatingActionButton';
import ContentAdd from 'material-ui/svg-icons/content/add';
import ContentClear from 'material-ui/svg-icons/content/clear';

const gridStyles = {
  root: {
    display: 'flex',
    flexDirection: 'column',
    flexWrap: 'wrap',
    justifyContent: 'space-around',
  },
  gridList: {
    overflowY: 'auto'
  },
  addButton: {
    display: 'flex',
    background: 'none',
    boxShadow: 'none'
  },
  tile: {
    background: '#444',
    borderRadius: '0.3em',
    padding: '1em',
    boxSizing: 'border-box'
  }
};

const listItemTitleStyle = {
  color: 'white',
  verticalAlign: 'middle',
  display: 'inline-block',
};

const listItemIconContainerStyle = {
  display: 'inline-block',
  textAlign: 'right'
};

const listItemIconStyle = {
  position: 'absolute',
  background: 'black',
  borderRadius: '1em',
  right: '1em',
  top: '1em'
};

export default class Dashboard extends Component {
  constructor(props){
    super(props);
    this.state = {
      threads: []
    };
  }

  addThread() {

  }

  removeThread(el) {
    let threadId = el.currentTarget.getAttribute('data-val');
    let threadRef = firebase.database().ref(`/threads/` + threadId);
    threadRef.remove();
  }

  componentDidMount() {
    this.threadsRef = firebase.database().ref(`/threads`);
    this.threadsRef.on('value', (resp) => {
      let threads = resp.val();
      let output = [];
      Object.keys(threads).forEach((threadKey) => {
          output.push({id: threadKey, ...threads[threadKey]});
      });
      this.setState({threads: output});
    });
  }

  render() {
    return (

        <DashboardComponent threads={this.state.threads}
                            addThread={this.addThread.bind(this)}
                            removeThread={this.removeThread.bind(this)}
        />

    );
  }
}

class DashboardComponent extends Component {
  constructor(props){
    super(props);
  }

  render() {

    return (

        <GridList style={gridStyles.gridList}>
          {
            this.props.threads.map((thread) => {
              return (
                <GridTile
                  style={
                    {
                      ...gridStyles.tile,
                      background: thread.photoUrl ? 'url(' + thread.photoUrl + ')' : 'grey'
                    }
                  }
                  key={thread.id}>
                    <Link to={`/thread/${thread.id}`}>

{thread.name}: {thread.id}

                    </Link>

                      <ContentClear style={listItemIconStyle} data-val={thread.id} onClick={this.props.removeThread}/>

                </GridTile>
              );
            })
          }
        </GridList>
        <FloatingActionButton style={gridStyles.addButton} onClick={this.props.addThread}>
          <ContentAdd />
        </FloatingActionButton>

    );
  }
}
<commit_msg>fix clickable area<commit_after>import React, { Component } from 'react';
import firebase from 'firebase';
import { Link } from 'react-router'
import {List, ListItem} from 'material-ui/List';
import {GridList, GridTile} from 'material-ui/GridList';
import FloatingActionButton from 'material-ui/FloatingActionButton';
import ContentAdd from 'material-ui/svg-icons/content/add';
import ContentClear from 'material-ui/svg-icons/content/clear';

const gridStyles = {
  root: {
    display: 'flex',
    flexDirection: 'column',
    flexWrap: 'wrap',
    justifyContent: 'space-around',
  },
  gridList: {
    overflowY: 'auto'
  },
  addButton: {
    display: 'flex',
    background: 'none',
    boxShadow: 'none'
  },
  tile: {
    background: '#444',
    borderRadius: '0.3em',
    padding: '1em',
    boxSizing: 'border-box'
  }
};

const listItemTitleStyle = {
  color: 'white',
  verticalAlign: 'middle',
  display: 'inline-block',
};

const listItemIconContainerStyle = {
  display: 'inline-block',
  textAlign: 'right'
};

const listItemIconStyle = {
  position: 'absolute',
  background: 'black',
  borderRadius: '1em',
  right: '1em',
  top: '1em'
};

export default class Dashboard extends Component {
  constructor(props){
    super(props);
    this.state = {
      threads: []
    };
  }

  addThread() {

  }

  removeThread(el) {
    let threadId = el.currentTarget.getAttribute('data-val');
    let threadRef = firebase.database().ref(`/threads/` + threadId);
    threadRef.remove();
  }

  componentDidMount() {
    this.threadsRef = firebase.database().ref(`/threads`);
    this.threadsRef.on('value', (resp) => {
      let threads = resp.val();
      let output = [];
      Object.keys(threads).forEach((threadKey) => {
          output.push({id: threadKey, ...threads[threadKey]});
      });
      this.setState({threads: output});
    });
  }

  render() {
    return (

        <DashboardComponent threads={this.state.threads}
                            addThread={this.addThread.bind(this)}
                            removeThread={this.removeThread.bind(this)}
        />

    );
  }
}

class DashboardComponent extends Component {
  constructor(props){
    super(props);
  }

  render() {

    return (

        <GridList style={gridStyles.gridList}>
          {
            this.props.threads.map((thread) => {
              return (
                <Link to={`/thread/${thread.id}`} key={thread.id}>
                  <GridTile
                    style={
                      {
                        ...gridStyles.tile,
                        background: thread.photoUrl ? 'url(' + thread.photoUrl + ')' : 'grey'
                      }
                    }>

{thread.name}: {thread.id}

                        <ContentClear style={listItemIconStyle} data-val={thread.id} onClick={this.props.removeThread}/>

                  </GridTile>
                </Link>
              );
            })
          }
        </GridList>
        <FloatingActionButton style={gridStyles.addButton} onClick={this.props.addThread}>
          <ContentAdd />
        </FloatingActionButton>

    );
  }
}
<|endoftext|>


<commit_before>"use strict";

function filterParams(pattern) {
	var first = new RegExp("\\\?" + pattern + "=[^&#]*&?");
	var rest = new RegExp("&" + pattern + "=[^&#]*", "g");

	return function(details) {

		var url = new URL(details.url);
		var newUrl = new URL(details.url);

		newUrl.search = url.search
			.replace(rest, "")
			.replace(first, "?");

		if (newUrl.search !== url.search) {
			return {redirectUrl: newUrl.href};
		}

		return {};
	}
}

var filters = [
	{
		urls: ["<all_urls>"],
		fn: filterParams("utm_(?:content|campaign|source|medium|term)")
	},
	{
		urls: ["*://*.aliexpress.com/*"],
		fn: filterParams("(?:ws_ab_test|btsid)")
	}
];

function event() {
	if (chrome.runtime.id === "deurchin@rahulg.io") {
		return chrome.webRequest.onBeforeSendHeaders;
	} else {
		return chrome.webRequest.onBeforeRequest;
	}
}

for (var idx = 0; idx < filters.length; idx++) {
	event().addListener(
		filters[idx].fn,
		{urls: filters[idx].urls},
		["blocking"]
	);
}
<commit_msg>use onBeforeRequest on firefox too<commit_after>"use strict";

function filterParams(pattern) {
	var first = new RegExp("\\\?" + pattern + "=[^&#]*&?");
	var rest = new RegExp("&" + pattern + "=[^&#]*", "g");

	return function(details) {

		var url = new URL(details.url);
		var newUrl = new URL(details.url);

		newUrl.search = url.search
			.replace(rest, "")
			.replace(first, "?");

		if (newUrl.search !== url.search) {
			return {redirectUrl: newUrl.href};
		}

		return {};
	}
}

var filters = [
	{
		urls: ["<all_urls>"],
		fn: filterParams("utm_(?:content|campaign|source|medium|term)")
	},
	{
		urls: ["*://*.aliexpress.com/*"],
		fn: filterParams("(?:ws_ab_test|btsid)")
	}
];

for (var idx = 0; idx < filters.length; idx++) {
	chrome.webRequest.onBeforeRequest.addListener(
		filters[idx].fn,
		{urls: filters[idx].urls},
		["blocking"]
	);
}
<|endoftext|>


<commit_before>//import //

var _elm_lang$core$Native_Platform = function() {

// EFFECT MANAGERS

var globalManagerInfo = {};

function makeManager(info, mainProcess)
{
	var router = {
		main: mainProcess,
		self: undefined
	};

	var tag = info.tag;
	var onEffects = info.onEffects;
	var onSelfMsg = info.onSelfMsg;

	function onMessage(msg, state)
	{
		if (msg.ctor === 'self')
		{
			return A3(onSelfMsg, router, msg._0, state);
		}

		var fx = msg._0;
		switch (tag)
		{
			case 'cmd':
				return A3(onEffects, router, fx.cmds, state);

			case 'sub':
				return A3(onEffects, router, fx.subs, state);

			case 'fx':
				return A4(onEffects, router, fx.cmds, fx.subs, state);
		}
	}

	var process = spawnLoop(info.init, onMessage);
	router.self = process;
	return process;
}

function sendToApp(router, msg)
{
	return A2(_elm_lang$core$Native_Scheduler.send, router.main, msg);
}

function sendToSelf(router, msg)
{
	return A2(_elm_lang$core$Native_Scheduler.send, router.self, {
		ctor: 'self',
		_0: msg
	});
}

// HELPER for STATEFUL LOOPS

function spawnLoop(init, onMessage)
{
	var andThen = _elm_lang$core$Native_Scheduler.andThen;

	function loop(state)
	{
		var handleMsg = _elm_lang$core$Native_Scheduler.receive(function(msg) {
			return onMessage(msg, state);
		});
		return A2(andThen, handleMsg, loop);
	}

	var task = A2(andThen, init, loop);

	return _elm_lang$core$Native_Scheduler.rawSpawn(task);
}

// PROGRAMS

function addPublicModule(object, name, main)
{
	var embed = main ? makeEmbed(name, main) : mainIsUndefined(name);

	object['embed'] = embed;

	object['fullscreen'] = function fullscreen(flags)
	{
		return embed(document.body, flags);
	};
}

function mainIsUndefined(name)
{
	return function(domNode)
	{
		var message = 'Cannot initialize module `' + name +
			'` because it has no `main` value!\nWhat should I show on screen?';
		domNode.innerHTML = errorHtml(message);
		throw new Error(message);
	};
}

function makeEmbed(moduleName, main)
{
	return function embed(rootDomNode, flags)
	{
		try
		{
			return makeEmbedHelp(moduleName, main, rootDomNode, flags);
		}
		catch (e)
		{
			rootDomNode.innerHTML = errorHtml(e.message);
			throw e;
		}
	};
}

function errorHtml(message)
{
	return '
'
		+ '
Oops! Something went wrong when starting your Elm program.
'
		+ '
' + message + '
'
		+ '
';
}

function makeEmbedHelp(moduleName, main, rootDomNode, flags)
{
	// main is a union type with one of the following tags: vdom, no-flags, flags
	// the follow section figures out what to do in each case.
	if (main.ctor === 'vdom')
	{
		_elm_lang$virtual_dom$Native_VirtualDom.staticProgram(rootDomNode, main._0);
		return {};
	}

	// Define: init, update, subscriptions, view, and makeRenderer
	var program = main._0;
	var init = makeInit(moduleName, main);
	var update = program.update;
	var subscriptions = program.subscriptions;
	var view = program.view;
	var makeRenderer = program.renderer;

	// ambient state
	var managers = {};
	var renderer;

	// init and update state in main process
	var initApp = _elm_lang$core$Native_Scheduler.nativeBinding(function(callback) {
		var results = init(flags);
		var model = results._0;
		renderer = makeRenderer(rootDomNode, enqueue, view(model));
		var cmds = results._1;
		var subs = subscriptions(model);
		dispatchEffects(managers, cmds, subs);
		callback(_elm_lang$core$Native_Scheduler.succeed(model));
	});

	function onMessage(msg, model)
	{
		return _elm_lang$core$Native_Scheduler.nativeBinding(function(callback) {
			var results = A2(update, msg, model);
			model = results._0;
			renderer.update(view(model));
			var cmds = results._1;
			var subs = subscriptions(model);
			dispatchEffects(managers, cmds, subs);
			callback(_elm_lang$core$Native_Scheduler.succeed(model));
		});
	}

	var mainProcess = spawnLoop(initApp, onMessage);

	function enqueue(msg)
	{
		_elm_lang$core$Native_Scheduler.rawSend(mainProcess, msg);
	}

	// setup all necessary effect managers
	for (var key in globalManagerInfo)
	{
		managers[key] = makeManager(globalManagerInfo[key], mainProcess);
	}

	// setup all foreign effects
	var foreign = {};
	var hasForeigns = false;

	for (var key in globalForeignCmds)
	{
		hasForeigns = true;
		setupCmd(key, managers, foreign);
	}

	for (var key in globalForeignSubs)
	{
		hasForeigns = true;
		setupSub(key, managers, foreign, mainProcess);
	}

	return hasForeigns ? { foreign: foreign } : {};
}

function makeInit(moduleName, main)
{
	var rawInit = main._0.init;

	if (main.ctor === 'no-flags')
	{
		return rawInit;
	}

	var flagDecoder = main._1;

	return function init(flags)
	{
		var result = A2(_elm_lang$core$Native_Json.run, flagDecoder, flags);
		if (result.ctor === 'Err')
		{
			throw new Error('You trying to initialize module `' + moduleName + '` with unexpected flags.\n'
				+ 'When trying to convert the flags to a usable Elm value, I run into this problem:\n\n'
				+ result._0
			);
		}
		return rawInit(result._0);
	}
}

// BAGS

function leaf(home)
{
	return function(value)
	{
		return {
			type: 'leaf',
			home: home,
			value: value
		};
	};
}

function batch(list)
{
	return {
		type: 'node',
		branches: list
	};
}

function map(tagger, bag)
{
	return {
		type: 'map',
		tagger: tagger,
		tree: bag
	}
}

// PIPE BAGS INTO EFFECT MANAGERS

function dispatchEffects(managers, cmdBag, subBag)
{
	var effectsDict = {};
	gatherEffects(true, cmdBag, effectsDict, null);
	gatherEffects(false, subBag, effectsDict, null);

	for (var home in effectsDict)
	{
		_elm_lang$core$Native_Scheduler.rawSend(managers[home], {
			ctor: 'fx',
			_0: effectsDict[home]
		});
	}
}

function gatherEffects(isCmd, bag, effectsDict, taggers)
{
	switch (bag.type)
	{
		case 'leaf':
			var home = bag.home;
			var effect = toEffect(isCmd, home, taggers, bag.value);
			effectsDict[home] = insert(isCmd, effect, effectsDict[home]);
			return;

		case 'node':
			var list = bag.branches;
			while (list.ctor !== '[]')
			{
				gatherEffects(isCmd, list._0, effectsDict, taggers);
				list = list._1;
			}
			return;

		case 'map':
			gatherEffects(isCmd, bag.tree, effectsDict, {
				tagger: bag.tagger,
				rest: taggers
			});
			return;
	}
}

function toEffect(isCmd, home, taggers, value)
{
	function applyTaggers(x)
	{
		while (taggers)
		{
			x = taggers.tagger(x);
			taggers = taggers.rest;
		}
		return x;
	}

	var map = isCmd
		? globalManagerInfo[home].cmdMap
		: globalManagerInfo[home].subMap;

	return A2(map, applyTaggers, value)
}

function insert(isCmd, newEffect, effects)
{
	effects = effects || {
		cmds: _elm_lang$core$Native_List.Nil,
		subs: _elm_lang$core$Native_List.Nil
	};
	if (isCmd)
	{
		effects.cmds = _elm_lang$core$Native_List.Cons(newEffect, effects.cmds);
		return effects;
	}
	effects.subs = _elm_lang$core$Native_List.Cons(newEffect, effects.subs);
	return effects;
}

// FOREIGN EFFECT LEAFS

var globalForeignCmds = {};
var globalForeignSubs = {};

function foreignCmd(name, converter)
{
	checkForeignName(name);
	globalForeignCmds[name] = converter;
	return leaf(name);
}

function foreignSub(name, converter)
{
	checkForeignName(name);
	globalForeignSubs[name] = converter;
	return leaf(name);
}

function checkForeignName(name)
{
	if (name in globalForeignCmds || name in globalForeignSubs)
	{
		throw new Error('There can only be one foreign effect named `'
			+ name + '`, but your program has multiple.');
	}
}

// SET UP FOREIGN EFFECTS

function setupCmd(name, managers, foreign)
{
	var converter = globalForeignCmds[name];
	var subs = [];

	// internal dispatching

	var init = _elm_lang$core$Native_Scheduler.succeed(null);

	function onMessage(msg, state)
	{
		var cmdList = msg._0.cmds;

		while (cmdList.ctor !== '[]')
		{
			var value = converter(cmdList._0);

			for (var i = 0; i < subs.length; i++)
			{
				subs[i](value);
			}

			cmdList = cmdList._1;
		}

		return init;
	}

	managers[name] = spawnLoop(init, onMessage);
	globalManagerInfo[name] = { cmdMap: F2(foreignCmdMap) };

	// external subscriptions

	function subscribe(callback)
	{
		subs.push(callback);
	}

	function unsubscribe(callback)
	{
		var index = subs.indexOf(callback);
		if (index >= 0)
		{
			subs.splice(index, 1);
		}
	}

	foreign[name] = {
		subscribe: subscribe,
		unsubscribe: unsubscribe
	};
}

// setup foreign subscriptions
function setupSub(name, managers, foreign, mainProcess)
{
	var converter = globalForeignSubs[name];
	var subs = _elm_lang$core$Native_List.Nil;

	// internal

	var init = _elm_lang$core$Native_Scheduler.succeed(null);

	function onMessage(msg, state)
	{
		subs = msg._0.subs;
		return init;
	}

	managers[name] = spawnLoop(init, onMessage);
	globalManagerInfo[name] = { subMap: F2(foreignSubMap) };

	// external

	function send(value)
	{
		var result = A2(_elm_lang$core$Json_Decode$decodeValue, converter, value);
		if (result.ctor === 'Err')
		{
			throw new Error('Trying to send an unexpected type of value through `' + name + '`:\n' + result._0);
		}

		var value = result._0;
		var temp = subs;
		while (temp.ctor !== '[]')
		{
			_elm_lang$core$Native_Scheduler.rawSend(mainProcess, temp._0(value));
			temp = temp._1;
		}
	}

	foreign[name] = { send: send };
}

// FOREIGN MAPS

function foreignCmdMap(tagger, value)
{
	return value;
}

function foreignSubMap(tagger, finalTagger)
{
	return function(value)
	{
		return tagger(finalTagger(value));
	};
}

return {
	// routers
	sendToApp: F2(sendToApp),
	sendToSelf: F2(sendToSelf),

	// global setup
	globalManagerInfo: globalManagerInfo,
	addPublicModule: addPublicModule,

	// effect bags
	leaf: leaf,
	batch: batch,
	map: F2(map),
	foreignCmd: foreignCmd,
	foreignSub: foreignSub
};

}();<commit_msg>Refactor Platform implementation for reactor<commit_after>//import //

var _elm_lang$core$Native_Platform = function() {

// PROGRAMS

function addPublicModule(object, name, main)
{
	var embed = main ? makeEmbed(name, main) : mainIsUndefined(name);

	object['embed'] = embed;

	object['fullscreen'] = function fullscreen(flags)
	{
		return embed(document.body, flags);
	};
}

// PROGRAM FAIL

function mainIsUndefined(name)
{
	return function(domNode)
	{
		var message = 'Cannot initialize module `' + name +
			'` because it has no `main` value!\nWhat should I show on screen?';
		domNode.innerHTML = errorHtml(message);
		throw new Error(message);
	};
}

function errorHtml(message)
{
	return '
'
		+ '
Oops! Something went wrong when starting your Elm program.
'
		+ '
' + message + '
'
		+ '
';
}

// PROGRAM SUCCESS

function makeEmbed(moduleName, main)
{
	return function embed(rootDomNode, flags)
	{
		try
		{
			var program = mainToProgram(moduleName, main);
			return makeEmbedHelp(moduleName, program, rootDomNode, flags);
		}
		catch (e)
		{
			rootDomNode.innerHTML = errorHtml(e.message);
			throw e;
		}
	};
}

// MAIN TO PROGRAM

function mainToProgram(moduleName, wrappedMain)
{
	var main = wrappedMain.main;

	if (typeof main.init === 'undefined')
	{
		var unit = _elm_lang$core$Native_Utils.Tuple0;
		return _elm_lang$html$Html_App$beginnerProgram({
			model: unit,
			update: A2(function() { return unit; }),
			view: function() { return main._0; }
		});
	}

	var flags = wrappedMain.flags;
	var init = flags
		? initWithFlags(moduleName, main.init, flags)
		: initWithoutFlags(moduleName, main.init);

	return {
		init: init,
		view: main.view,
		update: main.update,
		subscriptions: main.subscriptions,
		renderer: main.renderer
	};
}

function initWithoutFlags(moduleName, realInit)
{
	return function init(flags)
	{
		if (typeof flags !== 'undefined')
		{
			throw new Error(
				'You are giving module `' + moduleName + '` an argument in JavaScript.\n'
				+ 'This module does not take arguments though! You probably need to change the\n'
				+ 'initialization code to something like `Elm.' + moduleName + '.fullscreen()`'
			);
		}
		return realInit();
	};
}

function initWithFlags(moduleName, realInit, flagDecoder)
{
	return function init(flags)
	{
		var result = A2(_elm_lang$core$Native_Json.run, flagDecoder, flags);
		if (result.ctor === 'Err')
		{
			throw new Error(
				'You trying to initialize module `' + moduleName + '` with an unexpected argument.\n'
				+ 'When trying to convert it to a usable Elm value, I run into this problem:\n\n'
				+ result._0
			);
		}
		return realInit(result._0);
	};
}

// SETUP RUNTIME SYSTEM

function makeEmbedHelp(moduleName, program, rootDomNode, flags)
{
	var init = program.init;
	var update = program.update;
	var subscriptions = program.subscriptions;
	var view = program.view;
	var makeRenderer = program.renderer;

	// ambient state
	var managers = {};
	var renderer;

	// init and update state in main process
	var initApp = _elm_lang$core$Native_Scheduler.nativeBinding(function(callback) {
		var results = init(flags);
		var model = results._0;
		renderer = makeRenderer(rootDomNode, enqueue, view(model));
		var cmds = results._1;
		var subs = subscriptions(model);
		dispatchEffects(managers, cmds, subs);
		callback(_elm_lang$core$Native_Scheduler.succeed(model));
	});

	function onMessage(msg, model)
	{
		return _elm_lang$core$Native_Scheduler.nativeBinding(function(callback) {
			var results = A2(update, msg, model);
			model = results._0;
			renderer.update(view(model));
			var cmds = results._1;
			var subs = subscriptions(model);
			dispatchEffects(managers, cmds, subs);
			callback(_elm_lang$core$Native_Scheduler.succeed(model));
		});
	}

	var mainProcess = spawnLoop(initApp, onMessage);

	function enqueue(msg)
	{
		_elm_lang$core$Native_Scheduler.rawSend(mainProcess, msg);
	}

	var ports = setupEffects(managers, enqueue);

	return ports ? { ports: ports } : {};
}

// EFFECT MANAGERS

var effectManagers = {};

function setupEffects(managers, callback)
{
	var ports;

	// setup all necessary effect managers
	for (var key in effectManagers)
	{
		var manager = effectManagers[key];

		if (manager.isForeign)
		{
			ports = ports || {};
			ports[key] = manager.tag === 'cmd'
				? setupOutgoingPort(key)
				: setupIncomingPort(key, callback);
		}

		managers[key] = makeManager(manager, callback);
	}

	return ports;
}

function makeManager(info, callback)
{
	var router = {
		main: callback,
		self: undefined
	};

	var tag = info.tag;
	var onEffects = info.onEffects;
	var onSelfMsg = info.onSelfMsg;

	function onMessage(msg, state)
	{
		if (msg.ctor === 'self')
		{
			return A3(onSelfMsg, router, msg._0, state);
		}

		var fx = msg._0;
		switch (tag)
		{
			case 'cmd':
				return A3(onEffects, router, fx.cmds, state);

			case 'sub':
				return A3(onEffects, router, fx.subs, state);

			case 'fx':
				return A4(onEffects, router, fx.cmds, fx.subs, state);
		}
	}

	var process = spawnLoop(info.init, onMessage);
	router.self = process;
	return process;
}

function sendToApp(router, msg)
{
	return _elm_lang$core$Native_Scheduler.nativeBinding(function(callback)
	{
		router.main(msg);
		callback(_elm_lang$core$Native_Utils.Tuple0);
	});
}

function sendToSelf(router, msg)
{
	return A2(_elm_lang$core$Native_Scheduler.send, router.self, {
		ctor: 'self',
		_0: msg
	});
}

// HELPER for STATEFUL LOOPS

function spawnLoop(init, onMessage)
{
	var andThen = _elm_lang$core$Native_Scheduler.andThen;

	function loop(state)
	{
		var handleMsg = _elm_lang$core$Native_Scheduler.receive(function(msg) {
			return onMessage(msg, state);
		});
		return A2(andThen, handleMsg, loop);
	}

	var task = A2(andThen, init, loop);

	return _elm_lang$core$Native_Scheduler.rawSpawn(task);
}

// BAGS

function leaf(home)
{
	return function(value)
	{
		return {
			type: 'leaf',
			home: home,
			value: value
		};
	};
}

function batch(list)
{
	return {
		type: 'node',
		branches: list
	};
}

function map(tagger, bag)
{
	return {
		type: 'map',
		tagger: tagger,
		tree: bag
	}
}

// PIPE BAGS INTO EFFECT MANAGERS

function dispatchEffects(managers, cmdBag, subBag)
{
	var effectsDict = {};
	gatherEffects(true, cmdBag, effectsDict, null);
	gatherEffects(false, subBag, effectsDict, null);

	for (var home in effectsDict)
	{
		_elm_lang$core$Native_Scheduler.rawSend(managers[home], {
			ctor: 'fx',
			_0: effectsDict[home]
		});
	}
}

function gatherEffects(isCmd, bag, effectsDict, taggers)
{
	switch (bag.type)
	{
		case 'leaf':
			var home = bag.home;
			var effect = toEffect(isCmd, home, taggers, bag.value);
			effectsDict[home] = insert(isCmd, effect, effectsDict[home]);
			return;

		case 'node':
			var list = bag.branches;
			while (list.ctor !== '[]')
			{
				gatherEffects(isCmd, list._0, effectsDict, taggers);
				list = list._1;
			}
			return;

		case 'map':
			gatherEffects(isCmd, bag.tree, effectsDict, {
				tagger: bag.tagger,
				rest: taggers
			});
			return;
	}
}

function toEffect(isCmd, home, taggers, value)
{
	function applyTaggers(x)
	{
		while (taggers)
		{
			x = taggers.tagger(x);
			taggers = taggers.rest;
		}
		return x;
	}

	var map = isCmd
		? effectManagers[home].cmdMap
		: effectManagers[home].subMap;

	return A2(map, applyTaggers, value)
}

function insert(isCmd, newEffect, effects)
{
	effects = effects || {
		cmds: _elm_lang$core$Native_List.Nil,
		subs: _elm_lang$core$Native_List.Nil
	};
	if (isCmd)
	{
		effects.cmds = _elm_lang$core$Native_List.Cons(newEffect, effects.cmds);
		return effects;
	}
	effects.subs = _elm_lang$core$Native_List.Cons(newEffect, effects.subs);
	return effects;
}

// PORTS

function checkPortName(name)
{
	if (name in effectManagers)
	{
		throw new Error('There can only be one port named `' + name + '`, but your program has multiple.');
	}
}

// OUTGOING PORTS

function outgoingPort(name, converter)
{
	checkPortName(name);
	effectManagers[name] = {
		tag: 'cmd',
		cmdMap: outgoingPortMap,
		converter: converter,
		isForeign: true
	};
	return leaf(name);
}

var outgoingPortMap = F2(function cmdMap(tagger, value) {
	return value;
});

function setupOutgoingPort(name)
{
	var subs = [];
	var converter = effectManagers[name].converter;

	// CREATE MANAGER

	var init = _elm_lang$core$Native_Scheduler.succeed(null);

	function onEffects(router, cmdList, state)
	{
		while (cmdList.ctor !== '[]')
		{
			var value = converter(cmdList._0);
			for (var i = 0; i < subs.length; i++)
			{
				subs[i](value);
			}
			cmdList = cmdList._1;
		}
		return init;
	}

	effectManagers[name].init = init;
	effectManagers[name].onEffects = F3(onEffects);

	// PUBLIC API

	function subscribe(callback)
	{
		subs.push(callback);
	}

	function unsubscribe(callback)
	{
		var index = subs.indexOf(callback);
		if (index >= 0)
		{
			subs.splice(index, 1);
		}
	}

	return {
		subscribe: subscribe,
		unsubscribe: unsubscribe
	};
}

// INCOMING PORTS

function incomingPort(name, converter)
{
	checkPortName(name);
	effectManagers[name] = {
		tag: 'sub',
		subMap: incomingPortMap,
		converter: converter,
		isForeign: true
	};
	return leaf(name);
}

var incomingPortMap = F2(function subMap(tagger, finalTagger)
{
	return function(value)
	{
		return tagger(finalTagger(value));
	};
});

function setupIncomingPort(name, callback)
{
	var subs = _elm_lang$core$Native_List.Nil;
	var converter = effectManagers[name].converter;

	// CREATE MANAGER

	var init = _elm_lang$core$Native_Scheduler.succeed(null);

	function onEffects(router, subList, state)
	{
		subs = subList;
		return init;
	}

	effectManagers[name].init = init;
	effectManagers[name].onEffects = F3(onEffects);

	// PUBLIC API

	function send(value)
	{
		var result = A2(_elm_lang$core$Json_Decode$decodeValue, converter, value);
		if (result.ctor === 'Err')
		{
			throw new Error('Trying to send an unexpected type of value through port `' + name + '`:\n' + result._0);
		}

		var value = result._0;
		var temp = subs;
		while (temp.ctor !== '[]')
		{
			callback(temp._0(value));
			temp = temp._1;
		}
	}

	return { send: send };
}

return {
	// routers
	sendToApp: F2(sendToApp),
	sendToSelf: F2(sendToSelf),

	// global setup
	effectManagers: effectManagers,
	setupEffects: setupEffects,
	outgoingPort: outgoingPort,
	incomingPort: incomingPort,
	addPublicModule: addPublicModule,

	// effect bags
	leaf: leaf,
	batch: batch,
	map: F2(map)
};

}();<|endoftext|>


<commit_before>/*
 * Backpack - Skyscanner's Design System
 *
 * Copyright 2016-2019 Skyscanner Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import component from './src/BpkText';

export default component;
<commit_msg>Add flow strict comment to index (#1448)<commit_after>/*
 * Backpack - Skyscanner's Design System
 *
 * Copyright 2016-2019 Skyscanner Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* @flow strict */

import component from './src/BpkText';

export default component;
<|endoftext|>


<commit_before>/**
 *
 * Initilize TinyMCE editor with all required options
 */

// TinyMCE DomQuery variable
let dom = tinymce.dom.DomQuery

// Invisible space constant
const ZERO_SPACE = ''
const RAJE_SELECTOR = 'body#tinymce'
let flag = false

$(document).ready(function () {
  //hide footer
  $('footer.footer').hide()

  //attach whole body inside a placeholder div
  $('body').html(`<div id="raje_root">${$('body').html()}</div>`)

  $('header.page-header').addClass('mceNonEditable')

  tinymce.init({

    // Select the element to wrap
    selector: '#raje_root',

    // Set the styles of the content wrapped inside the element
    content_css: ['css/bootstrap.min.css', 'css/rash.css'],

    // Set plugins
    plugins: "fullscreen link codesample inline_code inline_quote section table noneditable raje_figure",

    // Remove menubar
    menubar: false,

    // Custom toolbar
    toolbar: 'undo redo bold italic link codesample superscript subscript inline_code | blockquote table raje_figure | section',

    // Setup full screen on init
    setup: function (editor) {

      // Set fullscreen
      editor.on('init', function (e) {

        editor.execCommand('mceFullScreen')
      })

      editor.on('keyDown', function (e) {

        // instance of the selected element
        let selectedElement = $(tinymce.activeEditor.selection.getNode())

        // When press enter
        if (e.keyCode == 13) {

          // When enter is pressed inside an header, not at the end of it
          if (selectedElement.is('h1,h2,h3,h4,h5,h6') && selectedElement.text().trim().length != tinymce.activeEditor.selection.getRng().startOffset) {

            section.addWithEnter()
            return false
          }

          /*
          if (selectedElement.is('p') && selectedElement.text().trim().indexOf('#') != -1) {
            let level = Rajemce.section.getLevelFromHash(selectedElement.text().trim())

            Rajemce.section.add(level, selectedElement.text().substring(level).trim())
          }*/
        }
      })
    },

    // Set default target
    default_link_target: "_blank",

    // Prepend protocol if the link starts with www
    link_assume_external_targets: true,

    // Hide target list
    target_list: false,

    // Hide title
    link_title: false,

    // Set formats
    formats: {
      inline_code: {
        inline: 'code'
      },
      inline_quote: {
        inline: 'q'
      }
    },

    // Remove "powered by tinymce"
    branding: false
  });
})
/**
 * raje_inline_code plugin RAJE
 */
tinymce.PluginManager.add('inline_code', function (editor, url) {

  // Add a button that opens a window
  editor.addButton('inline_code', {
    text: 'inline_code',
    icon: false,
    tooltip: 'Inline code',

    // Button behaviour
    onclick: function () {
      code.handle()
    }
  })

  code = {
    /**
     * Insert or exit from inline code element
     */
    handle: function () {

      let name = tinymce.activeEditor.selection.getNode().nodeName

      if (name == 'CODE')
        tinymce.activeEditor.formatter.remove('inline_code')

      else
        tinymce.activeEditor.formatter.apply('inline_code')
    }
  }
})

/**
 *  Inline quote plugin RAJE
 */
tinymce.PluginManager.add('inline_quote', function (editor, url) {

  // Add a button that handle the inline element
  editor.addButton('inline_quote', {
    text: 'inline_quote',
    icon: false,
    tooltip: 'Inline quote',

    // Button behaviour
    onclick: function () {
      quote.handle()
    }
  })

  quote = {
    /**
     * Insert or exit from inline quote element
     */
    handle: function () {

      let name = tinymce.activeEditor.selection.getNode().nodeName

      if (name == 'Q')
        tinymce.activeEditor.formatter.remove('inline_quote')

      else
        tinymce.activeEditor.formatter.apply('inline_quote')
    }
  }
})

/**
 * RASH section plugin RAJE
 */
tinymce.PluginManager.add('section', function (editor, url) {

  editor.addButton('section', {
    type: 'menubutton',
    text: 'Headings',
    title: 'heading',
    icons: false,

    // Sections sub menu
    menu: [{
      text: 'Heading 1.',
      onclick: function () {
        section.add(1)
      }
    }, {
      text: 'Heading 1.1.',
      onclick: function () {
        section.add(2)
      }
    }, {
      text: 'Heading 1.1.1.',
      onclick: function () {
        section.add(3)
      }
    }, {
      text: 'Heading 1.1.1.1.',
      onclick: function () {
        section.add(4)
      }
    }, {
      text: 'Heading 1.1.1.1.1.',
      onclick: function () {
        section.add(5)
      }
    }, {
      text: 'Heading 1.1.1.1.1.1.',
      onclick: function () {
        section.add(6)
      }
    }]
  })

  editor.on('keyDown', function (e) {

    // Check if a deletion is called
    if (e.keyCode == 8)
      flag = true
  })

  editor.on('NodeChange', function (e) {

    //tinymce.activeEditor.controlManager.get('section').setDisabled(true);
    /*

    let menu = tinymce.activeEditor.buttons['section'].menu

    // Update button menu
    for (let i = 0; i < 6; i++)
      menu[i].disabled = true

    // Save the reference of the selected node
    let selectedElement = tinymce.activeEditor.selection.getNode()

    // Check if the selected node is a paragraph only here can be added a new section
    if (tinymce.activeEditor.selection.getNode().nodeName == 'P') {

      // Get the deepness of the section which is the number of button to enable (+1 i.e. the 1st level subsection)
      let deepness = $(selectedElement).parents('section').length + 1
      for (let i = 0; i < deepness; i++)
        menu[i].disabled = false
    }

    editor.theme.panel.find('toolbar buttongroup').repaint()
    */

    if (flag) {
      flag = false
      section.updateSectionStructure()
    }
  })

  section = {

    /**
     * Function called when a new section needs to be attached, with buttons
     */
    add: function (level, text) {

      // Select current node
      let selectedElement = $(tinymce.activeEditor.selection.getNode())

      // Create the section
      let newSection = this.createSection(text ? text : selectedElement.html().trim(), level)

      tinymce.activeEditor.undoManager.transact(function () {

        // Check what kind of section needs to be inserted
        section.manageSection(selectedElement, newSection, level ? level : selectedElement.parentsUntil(RAJE_SELECTOR).length)

        // Remove the selected section
        selectedElement.remove()

        // Update editor content
        tinymce.triggerSave()
      })
    },

    /**
     * Function called when a new section needs to be attached, with buttons
     */
    addWithEnter: function (level) {

      // Select current node
      let selectedElement = $(tinymce.activeEditor.selection.getNode())

      level = level ? level : selectedElement.parentsUntil(RAJE_SELECTOR).length

      // Create the section
      let newSection = this.createSection(selectedElement.html().trim().substring(tinymce.activeEditor.selection.getRng().startOffset), level)

      tinymce.activeEditor.undoManager.transact(function () {

        // Check what kind of section needs to be inserted
        section.manageSection(selectedElement, newSection, level)

        // Remove the selected section
        selectedElement.html(selectedElement.html().trim().substring(0, tinymce.activeEditor.selection.getRng().startOffset))

        // Update editor
        tinymce.triggerSave()
      })
    },

    /**
     * Get the last inserted id
     */
    getNextId: function () {
      let id = 1
      dom('section[id]').each(function () {
        if (dom(this).attr('id').indexOf('section') > -1) {
          let currId = parseInt(dom(this).attr('id').replace('section', ''))
          id = id > currId ? id : currId
        }
      })
      return `section${id+1}`
    },

    /**
     * Retrieve and then remove every successive elements
     */
    getSuccessiveElements: function (element, deepness) {

      let successiveElements = $('

')

      while (deepness >= 0) {

        if (element.nextAll(':not(.footer)')) {

          // If the deepness is 0, only paragraph are saved (not sections)
          if (deepness == 0) {
            successiveElements.append(element.nextAll('p'))
            element.nextAll().remove('p')
          } else {
            successiveElements.append(element.nextAll())
            element.nextAll().remove()
          }
        }

        element = element.parent('section')
        deepness--
      }

      return $(successiveElements.html())
    },

    /**
     *
     */
    getLevelFromHash: function (text) {

      let level = 0
      text = text.substring(0, text.length >= 6 ? 6 : text.length)

      while (text.length > 0) {

        if (text.substring(text.length - 1) == '#')
          level++

          text = text.substring(0, text.length - 1)
      }

      return level
    },

    /**
     * Return JQeury object that represent the section
     */
    createSection: function (text, level) {
      // Create the section
      return $(`<section id="${this.getNextId()}"><h${level}>${ZERO_SPACE}${text}</h${level}></section>`)
    },

    /**
     * Check what kind of section needs to be added, and preceed
     */
    manageSection: function (selectedElement, newSection, level) {

      let deepness = $(selectedElement).parentsUntil(RAJE_SELECTOR).length - level + 1

      if (deepness >= 0) {

        // Get direct parent and ancestor reference
        let successiveElements = this.getSuccessiveElements(selectedElement, deepness)

        if (successiveElements.length)
          newSection.append(successiveElements)

        // CASE: sub section
        if (deepness == 0)
          selectedElement.after(newSection)

        // CASE: sibling section
        else if (deepness == 1)
          selectedElement.parent('section').after(newSection)

        // CASE: ancestor section at any uplevel
        else
          $(selectedElement.parents('section')[deepness - 1]).after(newSection)

        newSection.headingDimension()
      }
    },

    /**
     * Refresh editor and save the transaction inside the Undo buffer
     */
    commit: function () {

      // Refresh tinymce content and set the heading dimension
      tinymce.triggerSave()

      // Add the change to the undo manager
      tinymce.activeEditor.undoManager.add()
    },

    /**
     *
     */
    upgrade: function () {

      // Get the references of selected and parent section
      let selectedSection = $(tinymce.activeEditor.selection.getNode()).parent('section')
      let parentSection = selectedSection.parent('section')

      // If there is a parent section upgrade is allowed
      if (parentSection.length) {

        // Everything in here, is an atomic undo level
        tinymce.activeEditor.undoManager.transact(function () {

          // Save the section and detach
          let bodySection = $(selectedSection[0].outerHTML)
          selectedSection.detach()

          // Update dimension and move the section out
          parentSection.after(bodySection)

          // Refresh tinymce content and set the heading dimension
          bodySection.headingDimension()
          tinymce.triggerSave()
        })
      }
    },

    /**
     *
     */
    downgrade: function () {

      // Get the references of selected and sibling section
      let selectedSection = $(tinymce.activeEditor.selection.getNode()).parent('section')
      let siblingSection = selectedSection.prev('section')

      // If there is a previous sibling section downgrade is allowed
      if (siblingSection.length) {

        // Everything in here, is an atomic undo level
        tinymce.activeEditor.undoManager.transact(function () {

          // Save the section and detach
          let bodySection = $(selectedSection[0].outerHTML)
          selectedSection.detach()

          // Update dimension and move the section out
          siblingSection.append(bodySection)

          // Refresh tinymce content and set the heading dimension
          bodySection.headingDimension()
          tinymce.triggerSave()
        })
      }
    },

    /**
     *
     * After any delete, the editor must update the unvalidated elements
     */
    updateSectionStructure: function () {

      // Save selected element and ancestor section references
      let selectedElement = $(tinymce.activeEditor.selection.getNode())
      let ancestorSection = selectedElement.parents(RAJE_SELECTOR)

      // TODO update algorithm #issue96

      let toRemoveSections = []

      ancestorSection.find('section').each(function () {

        if ($(this).children().first().is('section')) {

          toRemoveSections.push($(this))
        }
      })

      // Get the list of the section without h1, those who have another section as first child
      //let toRemoveSections = ancestorSection.find('section:has(section:first-child)')

      // If there are sections to be removed
      if (toRemoveSections.length > 0) {

        // Move everything after
        selectedElement.after(toRemoveSections[length].html())

        toRemoveSections[0].remove()

        ancestorSection.children('section').headingDimension()
        tinymce.triggerSave()
      }
    },
  }
})

/**
 *
 */
tinymce.PluginManager.add('raje_figure', function (editor, url) {

  // Add a button that handle the inline element
  editor.addButton('raje_figure', {
    text: 'raje_figure',
    icon: false,
    tooltip: 'Add figure',

    // Button behaviour
    onclick: function () {
      figure.add()
    }
  })

  figure = {
    add: function () {

      /*
      let selectedElement = $(tinymce.activeEditor.selection.getNode())

      // Create the section
      let figure = `

                  Caption of the figure inserted through the element
                  img.

`

      tinymce.activeEditor.undoManager.transact(function () {
        selectedElement.after(figure)
        tinymce.triggerSave()
      })
      */
    }
  }
})

jQuery.fn.extend({
  headingDimension: function () {
    $(this).find('h1,h2,h3,h4,h5,h6').each(function () {
      var counter = 0;
      $(this).parents("section").each(function () {
        if ($(this).children("h1,h2,h3,h4,h5,h6").length > 0) {
          counter++;
        }
      });
      $(this).replaceWith("<h" + counter + ">" + $(this).html() + "</h" + counter + ">")
    });
  }
})<commit_msg>Modularised raje_figure plugin<commit_after>/**
 *
 * Initilize TinyMCE editor with all required options
 */

// TinyMCE DomQuery variable
let dom = tinymce.dom.DomQuery

// Invisible space constant
const ZERO_SPACE = ''
const RAJE_SELECTOR = 'body#tinymce'
let flag = false

$(document).ready(function () {
  //hide footer
  $('footer.footer').hide()

  //attach whole body inside a placeholder div
  $('body').html(`<div id="raje_root">${$('body').html()}</div>`)

  $('header.page-header').addClass('mceNonEditable')

  tinymce.init({

    // Select the element to wrap
    selector: '#raje_root',

    // Set the styles of the content wrapped inside the element
    content_css: ['css/bootstrap.min.css', 'css/rash.css'],

    // Set plugins
    plugins: "fullscreen link codesample raje_inlineCode raje_inlineQuote raje_section table noneditable raje_figure",

    // Remove menubar
    menubar: false,

    // Custom toolbar
    toolbar: 'undo redo bold italic link codesample superscript subscript raje_inlineCode | blockquote table raje_figure | raje_section',

    // Setup full screen on init
    setup: function (editor) {

      // Set fullscreen
      editor.on('init', function (e) {

        editor.execCommand('mceFullScreen')
      })

      editor.on('keyDown', function (e) {

        // instance of the selected element
        let selectedElement = $(tinymce.activeEditor.selection.getNode())

        // When press enter
        if (e.keyCode == 13) {

          // When enter is pressed inside an header, not at the end of it
          if (selectedElement.is('h1,h2,h3,h4,h5,h6') && selectedElement.text().trim().length != tinymce.activeEditor.selection.getRng().startOffset) {

            section.addWithEnter()
            return false
          }

          /*
          if (selectedElement.is('p') && selectedElement.text().trim().indexOf('#') != -1) {
            let level = Rajemce.section.getLevelFromHash(selectedElement.text().trim())

            Rajemce.section.add(level, selectedElement.text().substring(level).trim())
          }*/
        }
      })
    },

    // Set default target
    default_link_target: "_blank",

    // Prepend protocol if the link starts with www
    link_assume_external_targets: true,

    // Hide target list
    target_list: false,

    // Hide title
    link_title: false,

    // Set formats
    formats: {
      inline_code: {
        inline: 'code'
      },
      inline_quote: {
        inline: 'q'
      }
    },

    // Remove "powered by tinymce"
    branding: false
  });
})
/**
 * raje_inline_code plugin RAJE
 */
tinymce.PluginManager.add('raje_inlineCode', function (editor, url) {

  // Add a button that opens a window
  editor.addButton('inline_code', {
    text: 'inline_code',
    icon: false,
    tooltip: 'Inline code',

    // Button behaviour
    onclick: function () {
      code.handle()
    }
  })

  code = {
    /**
     * Insert or exit from inline code element
     */
    handle: function () {

      let name = tinymce.activeEditor.selection.getNode().nodeName

      if (name == 'CODE')
        tinymce.activeEditor.formatter.remove('inline_code')

      else
        tinymce.activeEditor.formatter.apply('inline_code')
    }
  }
})

/**
 *  Inline quote plugin RAJE
 */
tinymce.PluginManager.add('raje_inlineQuote', function (editor, url) {

  // Add a button that handle the inline element
  editor.addButton('inline_quote', {
    text: 'inline_quote',
    icon: false,
    tooltip: 'Inline quote',

    // Button behaviour
    onclick: function () {
      quote.handle()
    }
  })

  quote = {
    /**
     * Insert or exit from inline quote element
     */
    handle: function () {

      let name = tinymce.activeEditor.selection.getNode().nodeName

      if (name == 'Q')
        tinymce.activeEditor.formatter.remove('inline_quote')

      else
        tinymce.activeEditor.formatter.apply('inline_quote')
    }
  }
})

/**
 * RASH section plugin RAJE
 */
tinymce.PluginManager.add('raje_section', function (editor, url) {

  editor.addButton('raje_section', {
    type: 'menubutton',
    text: 'Headings',
    title: 'heading',
    icons: false,

    // Sections sub menu
    menu: [{
      text: 'Heading 1.',
      onclick: function () {
        section.add(1)
      }
    }, {
      text: 'Heading 1.1.',
      onclick: function () {
        section.add(2)
      }
    }, {
      text: 'Heading 1.1.1.',
      onclick: function () {
        section.add(3)
      }
    }, {
      text: 'Heading 1.1.1.1.',
      onclick: function () {
        section.add(4)
      }
    }, {
      text: 'Heading 1.1.1.1.1.',
      onclick: function () {
        section.add(5)
      }
    }, {
      text: 'Heading 1.1.1.1.1.1.',
      onclick: function () {
        section.add(6)
      }
    }]
  })

  editor.on('keyDown', function (e) {

    // Check if a deletion is called
    if (e.keyCode == 8)
      flag = true
  })

  editor.on('NodeChange', function (e) {

    //tinymce.activeEditor.controlManager.get('section').setDisabled(true);
    /*

    let menu = tinymce.activeEditor.buttons['section'].menu

    // Update button menu
    for (let i = 0; i < 6; i++)
      menu[i].disabled = true

    // Save the reference of the selected node
    let selectedElement = tinymce.activeEditor.selection.getNode()

    // Check if the selected node is a paragraph only here can be added a new section
    if (tinymce.activeEditor.selection.getNode().nodeName == 'P') {

      // Get the deepness of the section which is the number of button to enable (+1 i.e. the 1st level subsection)
      let deepness = $(selectedElement).parents('section').length + 1
      for (let i = 0; i < deepness; i++)
        menu[i].disabled = false
    }

    editor.theme.panel.find('toolbar buttongroup').repaint()
    */

    if (flag) {
      flag = false
      section.updateSectionStructure()
    }
  })

  section = {

    /**
     * Function called when a new section needs to be attached, with buttons
     */
    add: function (level, text) {

      // Select current node
      let selectedElement = $(tinymce.activeEditor.selection.getNode())

      // Create the section
      let newSection = this.create(text ? text : selectedElement.html().trim(), level)

      tinymce.activeEditor.undoManager.transact(function () {

        // Check what kind of section needs to be inserted
        section.manageSection(selectedElement, newSection, level ? level : selectedElement.parentsUntil(RAJE_SELECTOR).length)

        // Remove the selected section
        selectedElement.remove()

        // Update editor content
        tinymce.triggerSave()
      })
    },

    /**
     * Function called when a new section needs to be attached, with buttons
     */
    addWithEnter: function (level) {

      // Select current node
      let selectedElement = $(tinymce.activeEditor.selection.getNode())

      level = level ? level : selectedElement.parentsUntil(RAJE_SELECTOR).length

      // Create the section
      let newSection = this.create(selectedElement.html().trim().substring(tinymce.activeEditor.selection.getRng().startOffset), level)

      tinymce.activeEditor.undoManager.transact(function () {

        // Check what kind of section needs to be inserted
        section.manageSection(selectedElement, newSection, level)

        // Remove the selected section
        selectedElement.html(selectedElement.html().trim().substring(0, tinymce.activeEditor.selection.getRng().startOffset))

        // Update editor
        tinymce.triggerSave()
      })
    },

    /**
     * Get the last inserted id
     */
    getNextId: function () {
      let id = 1
      $('section[id]').each(function () {
        if ($(this).attr('id').indexOf('section') > -1) {
          let currId = parseInt($(this).attr('id').replace('section', ''))
          id = id > currId ? id : currId
        }
      })
      return `section${id+1}`
    },

    /**
     * Retrieve and then remove every successive elements
     */
    getSuccessiveElements: function (element, deepness) {

      let successiveElements = $('

')

      while (deepness >= 0) {

        if (element.nextAll(':not(.footer)')) {

          // If the deepness is 0, only paragraph are saved (not sections)
          if (deepness == 0) {
            successiveElements.append(element.nextAll('p'))
            element.nextAll().remove('p')
          } else {
            successiveElements.append(element.nextAll())
            element.nextAll().remove()
          }
        }

        element = element.parent('section')
        deepness--
      }

      return $(successiveElements.html())
    },

    /**
     *
     */
    getLevelFromHash: function (text) {

      let level = 0
      text = text.substring(0, text.length >= 6 ? 6 : text.length)

      while (text.length > 0) {

        if (text.substring(text.length - 1) == '#')
          level++

          text = text.substring(0, text.length - 1)
      }

      return level
    },

    /**
     * Return JQeury object that represent the section
     */
    create: function (text, level) {
      // Create the section
      return $(`<section id="${this.getNextId()}"><h${level}>${ZERO_SPACE}${text}</h${level}></section>`)
    },

    /**
     * Check what kind of section needs to be added, and preceed
     */
    manageSection: function (selectedElement, newSection, level) {

      let deepness = $(selectedElement).parentsUntil(RAJE_SELECTOR).length - level + 1

      if (deepness >= 0) {

        // Get direct parent and ancestor reference
        let successiveElements = this.getSuccessiveElements(selectedElement, deepness)

        if (successiveElements.length)
          newSection.append(successiveElements)

        // CASE: sub section
        if (deepness == 0)
          selectedElement.after(newSection)

        // CASE: sibling section
        else if (deepness == 1)
          selectedElement.parent('section').after(newSection)

        // CASE: ancestor section at any uplevel
        else
          $(selectedElement.parents('section')[deepness - 1]).after(newSection)

        newSection.headingDimension()
      }
    },

    /**
     * Refresh editor and save the transaction inside the Undo buffer
     */
    commit: function () {

      // Refresh tinymce content and set the heading dimension
      tinymce.triggerSave()

      // Add the change to the undo manager
      tinymce.activeEditor.undoManager.add()
    },

    /**
     *
     */
    upgrade: function () {

      // Get the references of selected and parent section
      let selectedSection = $(tinymce.activeEditor.selection.getNode()).parent('section')
      let parentSection = selectedSection.parent('section')

      // If there is a parent section upgrade is allowed
      if (parentSection.length) {

        // Everything in here, is an atomic undo level
        tinymce.activeEditor.undoManager.transact(function () {

          // Save the section and detach
          let bodySection = $(selectedSection[0].outerHTML)
          selectedSection.detach()

          // Update dimension and move the section out
          parentSection.after(bodySection)

          // Refresh tinymce content and set the heading dimension
          bodySection.headingDimension()
          tinymce.triggerSave()
        })
      }
    },

    /**
     *
     */
    downgrade: function () {

      // Get the references of selected and sibling section
      let selectedSection = $(tinymce.activeEditor.selection.getNode()).parent('section')
      let siblingSection = selectedSection.prev('section')

      // If there is a previous sibling section downgrade is allowed
      if (siblingSection.length) {

        // Everything in here, is an atomic undo level
        tinymce.activeEditor.undoManager.transact(function () {

          // Save the section and detach
          let bodySection = $(selectedSection[0].outerHTML)
          selectedSection.detach()

          // Update dimension and move the section out
          siblingSection.append(bodySection)

          // Refresh tinymce content and set the heading dimension
          bodySection.headingDimension()
          tinymce.triggerSave()
        })
      }
    },

    /**
     *
     * After any delete, the editor must update the unvalidated elements
     */
    updateSectionStructure: function () {

      // Save selected element and ancestor section references
      let selectedElement = $(tinymce.activeEditor.selection.getNode())
      let ancestorSection = selectedElement.parents(RAJE_SELECTOR)

      // TODO update algorithm #issue96

      let toRemoveSections = []

      ancestorSection.find('section').each(function () {

        if ($(this).children().first().is('section')) {

          toRemoveSections.push($(this))
        }
      })

      // Get the list of the section without h1, those who have another section as first child
      //let toRemoveSections = ancestorSection.find('section:has(section:first-child)')

      // If there are sections to be removed
      if (toRemoveSections.length > 0) {

        // Move everything after
        selectedElement.after(toRemoveSections[length].html())

        toRemoveSections[0].remove()

        ancestorSection.children('section').headingDimension()
        tinymce.triggerSave()
      }
    },
  }
})

/**
 *
 */
tinymce.PluginManager.add('raje_figure', function (editor, url) {

  // Add a button that handle the inline element
  editor.addButton('raje_figure', {
    text: 'raje_figure',
    icon: false,
    tooltip: 'Add figure',

    // Button behaviour
    onclick: function () {

      editor.windowManager.open({
        title: 'Select image',
        body: [{
          type: 'textbox',
          name: 'url',
          label: 'url'
        }, {
          type: 'textbox',
          name: 'alt',
          label: 'alt'
        }],
        onSubmit: function (e) {
          figure.add(e.data.url, e.data.alt)
        }
      })
    }
  })

  figure = {

    /**
     * s
     */
    add: function (url, alt) {

      // Get the referece of the selected element
      let selectedElement = $(tinymce.activeEditor.selection.getNode())

      if (selectedElement.text().trim().length != 0) {
        let tmp = $('

')
        selectedElement.after(tmp)

        selectedElement = tmp
      }

      // Create the object of the figure
      let newFigure = this.create(url, alt)

      tinymce.activeEditor.undoManager.transact(function () {

        selectedElement.append(newFigure)
        tinymce.triggerSave()
      })
    },

    /**
     *
     */
    create: function (url, alt) {
      return $(`<figure id="${this.getNextId()}"><p><img src="${url}" alt="${alt}"/></p><figcaption>Caption.</figcaption></figure>`)
    },

    /**
     *
     */
    getNextId: function () {
      let id = 1
      $('figurebox_selector').each(function () {
        if ($(this).attr('id').indexOf('section') > -1) {
          let currId = parseInt($(this).attr('id').replace('figure', ''))
          id = id > currId ? id : currId
        }
      })
      return `figure_${id+1}`
    }
  }
})

jQuery.fn.extend({
  headingDimension: function () {
    $(this).find('h1,h2,h3,h4,h5,h6').each(function () {
      var counter = 0;
      $(this).parents("section").each(function () {
        if ($(this).children("h1,h2,h3,h4,h5,h6").length > 0) {
          counter++;
        }
      });
      $(this).replaceWith("<h" + counter + ">" + $(this).html() + "</h" + counter + ">")
    });
  }
})<|endoftext|>


<commit_before>import React, {Component, PropTypes} from "react";
import {connect} from "react-redux";
import {bindActionCreators} from "redux";
import "react-select/dist/react-select.css";
import ReactSelect from "react-select";
import {get} from "redux/modules/MolgenisApi";

const propTypes = {
  loadOptions: React.PropTypes.func,
  onChange: React.PropTypes.func
};

/**
 * This is the dumb presentation component for the Entity select box.
 */
class EntitySelectBox extends Component {
  render() {
    return (
      <ReactSelect.Async cache={null}
                         filterOptions={false}
                         {...this.props}/>
    )
  }
}
EntitySelectBox.propTypes = propTypes;

// these two methods are used to wrap a container component around the presentation component above
const mapStateToProps = ({session: {server, token}}, {entityName, getQuery, attrs, getLabel}) => {
  // retrieval of options happens in view state, define here how to retrieve them.
  function getUrl(input = '') {
    const q = getQuery(input)
    const params = {q, attrs}
    const query = Object.keys(params)
      .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
      .join('&');
    return `/v2/${entityName}?${query}`;
  }

  const loadOptions = (input) => {
    return get(server, getUrl(input), token).then((json) => {
      return {
        options: json.items.map(item => ({label: getLabel(item), value: item})),
        complete: false
      }
    })
  }
  return {loadOptions};
}

const mapDispatchToProps = {};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(EntitySelectBox);
<commit_msg>explicitly specify which props to transfer<commit_after>import React, {Component, PropTypes} from "react";
import {connect} from "react-redux";
import {bindActionCreators} from "redux";
import "react-select/dist/react-select.css";
import ReactSelect from "react-select";
import {get} from "redux/modules/MolgenisApi";

const propTypes = {
  loadOptions: React.PropTypes.func,
  onChange: React.PropTypes.func
};

/**
 * This is the dumb presentation component for the Entity select box.
 */
class EntitySelectBox extends Component {
  render() {
    const {loadOptions, onChange} = this.props
    return <ReactSelect.Async cache={null}
                              filterOptions={false}
                              loadOptions={loadOptions}
                              onChange={onChange}/>
  }
}
EntitySelectBox.propTypes = propTypes;

// these two methods are used to wrap a container component around the presentation component above
const mapStateToProps = ({session: {server, token}}, {entityName, getQuery, attrs, getLabel}) => {
  // retrieval of options happens in view state, define here how to retrieve them.
  function getUrl(input = '') {
    const q = getQuery(input)
    const params = {q, attrs}
    const query = Object.keys(params)
      .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
      .join('&');
    return `/v2/${entityName}?${query}`;
  }

  const loadOptions = (input) => {
    return get(server, getUrl(input), token).then((json) => {
      return {
        options: json.items.map(item => ({label: getLabel(item), value: item})),
        complete: false
      }
    })
  }
  return {loadOptions};
}

const mapDispatchToProps = {};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(EntitySelectBox);
<|endoftext|>


<commit_before>function _addCurationButton() {
    $('.g-folder-actions-menu').append(girder.templates.curation_button());
}

// add curation button to hiearchy widget
girder.wrap(girder.views.HierarchyWidget, 'render', function (render) {
    render.call(this);

    if (this.parentModel.get('_modelType') === 'folder') {
        // add button if an admin or if curation is enabled
        if (girder.currentUser.get('admin')) {
            _addCurationButton();
        } else {
            girder.restRequest({
                path: 'folder/' + this.parentModel.get('_id') + '/curation'
            }).done(_.bind(function (resp) {
                if (resp.enabled) {
                    _addCurationButton();
                }
            }, this));
        }
    }

    return this;
});

// launch modal when curation button is clicked
girder.views.HierarchyWidget.prototype.events['click .g-curation-button'] = function (e) {
    new girder.views.CurationDialog({
        el: $('#g-dialog-container'),
        parentView: this,
        folder: this.parentModel
    });
};

// curation dialog
girder.views.CurationDialog = girder.View.extend({
    events: {
        'click #g-curation-enable': function (event) {
            event.preventDefault();
            this._save('Enabled folder curation', {
                id: this.folder.get('_id'),
                enabled: true
            });
        },
        'click #g-curation-disable': function (event) {
            event.preventDefault();
            this._save('Disabled folder curation', {
                id: this.folder.get('_id'),
                enabled: false
            });
        },
        'click #g-curation-request': function (event) {
            event.preventDefault();
            this._save('Submitted folder for admin approval', {
                id: this.folder.get('_id'),
                status: 'requested'
            });
        },
        'click #g-curation-approve': function (event) {
            event.preventDefault();
            this._save('Approved curated folder', {
                id: this.folder.get('_id'),
                status: 'approved'
            });
        },
        'click #g-curation-reject': function (event) {
            event.preventDefault();
            this._save('Rejected curated folder', {
                id: this.folder.get('_id'),
                status: 'construction'
            });
        },
        'click #g-curation-reopen': function (event) {
            event.preventDefault();
            this._save('Reopened curated folder', {
                id: this.folder.get('_id'),
                status: 'construction'
            });
        }
    },

    initialize: function (settings) {
        this.folder = this.parentView.parentModel;
        this.curation = {timeline: []};
        girder.restRequest({
            path: 'folder/' + this.folder.get('_id') + '/curation'
        }).done(_.bind(function (resp) {
            this.curation = resp;
            this.render();
        }, this));
    },

    render: function (refresh) {
        var q = this.$el.html(girder.templates.curation_dialog({
            folder: this.folder,
            curation: this.curation,
            moment: window.moment
        }));

        if (!refresh) {
            q.girderModal(this);
        }

        // show only relevant action buttons
        $('.g-curation-action-container button').hide();
        if (this.curation.enabled) {
            if (this.curation.status === 'construction') {
                $('#g-curation-request').show();
            }
            if (girder.currentUser.get('admin')) {
                $('#g-curation-disable').show();
                if (this.curation.status === 'requested') {
                    $('#g-curation-approve').show();
                    $('#g-curation-reject').show();
                }
                if (this.curation.status === 'approved') {
                    $('#g-curation-reopen').show();
                }
            }
        } else {
            if (girder.currentUser.get('admin')) {
                $('#g-curation-enable').show();
            }
        }

        return this;
    },

    _save: function (successText, data) {
        girder.restRequest({
            type: 'PUT',
            path: 'folder/' + this.folder.get('_id') + '/curation',
            data: data
        }).done(_.bind(function (resp) {
            this.curation = resp;
            this.render(true);
            girder.events.trigger('g:alert', {
                icon: 'ok',
                text: successText,
                type: 'success',
                timeout: 4000
            });
        }, this)).error(_.bind(function (resp) {
            this.$('#g-curation-error-message').text(
                resp.responseJSON.message
            );
        }, this));
    }
});
<commit_msg>Ignore eslint error<commit_after>function _addCurationButton() {
    $('.g-folder-actions-menu').append(girder.templates.curation_button());
}

// add curation button to hiearchy widget
girder.wrap(girder.views.HierarchyWidget, 'render', function (render) {
    render.call(this);

    if (this.parentModel.get('_modelType') === 'folder') {
        // add button if an admin or if curation is enabled
        if (girder.currentUser.get('admin')) {
            _addCurationButton();
        } else {
            girder.restRequest({
                path: 'folder/' + this.parentModel.get('_id') + '/curation'
            }).done(_.bind(function (resp) {
                if (resp.enabled) {
                    _addCurationButton();
                }
            }, this));
        }
    }

    return this;
});

// launch modal when curation button is clicked
girder.views.HierarchyWidget.prototype.events['click .g-curation-button'] = function (e) {
    /* eslint-disable */
    new girder.views.CurationDialog({
        el: $('#g-dialog-container'),
        parentView: this,
        folder: this.parentModel
    });
    /* eslint-enable */
};

// curation dialog
girder.views.CurationDialog = girder.View.extend({
    events: {
        'click #g-curation-enable': function (event) {
            event.preventDefault();
            this._save('Enabled folder curation', {
                id: this.folder.get('_id'),
                enabled: true
            });
        },
        'click #g-curation-disable': function (event) {
            event.preventDefault();
            this._save('Disabled folder curation', {
                id: this.folder.get('_id'),
                enabled: false
            });
        },
        'click #g-curation-request': function (event) {
            event.preventDefault();
            this._save('Submitted folder for admin approval', {
                id: this.folder.get('_id'),
                status: 'requested'
            });
        },
        'click #g-curation-approve': function (event) {
            event.preventDefault();
            this._save('Approved curated folder', {
                id: this.folder.get('_id'),
                status: 'approved'
            });
        },
        'click #g-curation-reject': function (event) {
            event.preventDefault();
            this._save('Rejected curated folder', {
                id: this.folder.get('_id'),
                status: 'construction'
            });
        },
        'click #g-curation-reopen': function (event) {
            event.preventDefault();
            this._save('Reopened curated folder', {
                id: this.folder.get('_id'),
                status: 'construction'
            });
        }
    },

    initialize: function (settings) {
        this.folder = this.parentView.parentModel;
        this.curation = {timeline: []};
        girder.restRequest({
            path: 'folder/' + this.folder.get('_id') + '/curation'
        }).done(_.bind(function (resp) {
            this.curation = resp;
            this.render();
        }, this));
    },

    render: function (refresh) {
        var q = this.$el.html(girder.templates.curation_dialog({
            folder: this.folder,
            curation: this.curation,
            moment: window.moment
        }));

        if (!refresh) {
            q.girderModal(this);
        }

        // show only relevant action buttons
        $('.g-curation-action-container button').hide();
        if (this.curation.enabled) {
            if (this.curation.status === 'construction') {
                $('#g-curation-request').show();
            }
            if (girder.currentUser.get('admin')) {
                $('#g-curation-disable').show();
                if (this.curation.status === 'requested') {
                    $('#g-curation-approve').show();
                    $('#g-curation-reject').show();
                }
                if (this.curation.status === 'approved') {
                    $('#g-curation-reopen').show();
                }
            }
        } else {
            if (girder.currentUser.get('admin')) {
                $('#g-curation-enable').show();
            }
        }

        return this;
    },

    _save: function (successText, data) {
        girder.restRequest({
            type: 'PUT',
            path: 'folder/' + this.folder.get('_id') + '/curation',
            data: data
        }).done(_.bind(function (resp) {
            this.curation = resp;
            this.render(true);
            girder.events.trigger('g:alert', {
                icon: 'ok',
                text: successText,
                type: 'success',
                timeout: 4000
            });
        }, this)).error(_.bind(function (resp) {
            this.$('#g-curation-error-message').text(
                resp.responseJSON.message
            );
        }, this));
    }
});
<|endoftext|>


<commit_before>var fs = require("fs");
var path = require("path");
var esprima = require("../process/esprima/index");
var getVariables = require("../process/compile/variables");
var typescript = require("../process/typescript/typescript");
var check = function (root) {
    var rest = [].concat.apply([], arguments);
    var map = {
        devicePixelRatio: 1,
        "screen": true,
        "window": true,
        "document": true,
        "location": true,
        "navigator": true,
        "XMLHttpRequest": true,
        "history": true,
        "Image": true,
        "self": true,
        "modules": true,
        "init": true,
        "put": true,
        "state": true
    }, needs = {};
    var list = function () {
        Object.keys(needs).filter(k => !map[k]).forEach(function (k) {
            var key = k;
            if (!global[key]) console.log(key, needs[k]);
        });
    }
    var run = function () {
        if (!rest.length) return list();
        var fullpath = rest.pop();
        fs.access(fullpath, function (error) {
            if (error) return console.error(error);
            fs.stat(fullpath, function (error, stats) {
                if (error) return console.error(error);
                if (stats.isDirectory()) {
                    fs.readdir(fullpath, function (error, names) {
                        if (error) return console.error(error);
                        rest.push.apply(rest, names.map(n => path.join(fullpath, n)));
                        run();
                    });
                    return;
                }
                if (stats.isFile()) {
                    var basename = path.relative(root, fullpath);
                    basename = basename.replace(/[\\\/]/g, '$');
                    if (/\.json$/i.test(basename)) {
                        map[basename.replace(/\.json$/i, "")] = true;
                    }
                    if (/\.(html?|xml)$/i.test(basename)) {
                        map[path.basename(basename).replace(/\.(html?|xml)$/i, "")] = true;
                    }
                    if (!/\.[jt]sx?$/i.test(fullpath)) return run();
                    map[basename.replace(/\.[jt]sx?$/i, "")] = true;
                    fs.readFile(fullpath, function (error, data) {
                        if (error) return console.error(error);
                        try {
                            var jst = esprima.parse(typescript.transpile(String(data)));
                            var {
                                unDeclaredVariables: undeclares
                            } = getVariables(jst);
                            delete undeclares[path.basename(fullpath).replace(/\.[jt]sx?$/i, '')];
                            Object.keys(undeclares).map(k => k).forEach(k => {
                                if (!needs[k]) needs[k] = [];
                                needs[k].push(basename);
                            });
                        } catch (e) {
                            console.error(basename, String(e));
                        }
                        run();
                    });
                    return;
                }
                run();
            });
        });
    }
    run();
}
check('coms/zimoli');<commit_msg>添加Event变更<commit_after>var fs = require("fs");
var path = require("path");
var esprima = require("../process/esprima/index");
var getVariables = require("../process/compile/variables");
var typescript = require("../process/typescript/typescript");
var check = function (root) {
    var rest = [].concat.apply([], arguments);
    var map = {
        devicePixelRatio: 1,
        "screen": true,
        "window": true,
        "document": true,
        "location": true,
        "navigator": true,
        "XMLHttpRequest": true,
        "history": true,
        "Image": true,
        "Event": true,
        "self": true,
        "modules": true,
        "init": true,
        "put": true,
        "state": true
    }, needs = {};
    var list = function () {
        Object.keys(needs).filter(k => !map[k]).forEach(function (k) {
            var key = k;
            if (!global[key]) console.log(key, needs[k]);
        });
    }
    var run = function () {
        if (!rest.length) return list();
        var fullpath = rest.pop();
        fs.access(fullpath, function (error) {
            if (error) return console.error(error);
            fs.stat(fullpath, function (error, stats) {
                if (error) return console.error(error);
                if (stats.isDirectory()) {
                    fs.readdir(fullpath, function (error, names) {
                        if (error) return console.error(error);
                        rest.push.apply(rest, names.map(n => path.join(fullpath, n)));
                        run();
                    });
                    return;
                }
                if (stats.isFile()) {
                    var basename = path.relative(root, fullpath);
                    basename = basename.replace(/[\\\/]/g, '$');
                    if (/\.json$/i.test(basename)) {
                        map[basename.replace(/\.json$/i, "")] = true;
                    }
                    if (/\.(html?|xml)$/i.test(basename)) {
                        map[path.basename(basename).replace(/\.(html?|xml)$/i, "")] = true;
                    }
                    if (!/\.[jt]sx?$/i.test(fullpath)) return run();
                    map[basename.replace(/\.[jt]sx?$/i, "")] = true;
                    fs.readFile(fullpath, function (error, data) {
                        if (error) return console.error(error);
                        try {
                            var jst = esprima.parse(typescript.transpile(String(data)));
                            var {
                                unDeclaredVariables: undeclares
                            } = getVariables(jst);
                            delete undeclares[path.basename(fullpath).replace(/\.[jt]sx?$/i, '')];
                            Object.keys(undeclares).map(k => k).forEach(k => {
                                if (!needs[k]) needs[k] = [];
                                needs[k].push(basename);
                            });
                        } catch (e) {
                            console.error(basename, String(e));
                        }
                        run();
                    });
                    return;
                }
                run();
            });
        });
    }
    run();
}
check('coms/zimoli');<|endoftext|>


<commit_before>// eslint-disable-next-line no-unused-vars
import { createElement, Component, memo, Fragment } from "react";

function Foo() {
	return
I'm memoed
;
}

const Memoed = memo(Foo);

export default class DevtoolsDemo extends Component {
	render() {
		return (

memo()

functional component:

				<Memoed />

		);
	}
}
<commit_msg>Add Suspense/lazy to devtools demo<commit_after>// eslint-disable-next-line no-unused-vars
import { createElement, Component, memo, Fragment, Suspense, lazy } from "react";

function Foo() {
	return
I'm memoed
;
}

function LazyComp() {
	return
I'm (fake) lazy loaded
;
}

console.log(lazy);
const Lazy = lazy(() => Promise.resolve({ default: LazyComp }));

const Memoed = memo(Foo);

export default class DevtoolsDemo extends Component {
	render() {
		return (

memo()

functional component:

				<Memoed />

lazy()

functional component:

				<Suspense fallback={
Loading (fake) lazy loaded component...
}>
					<Lazy />
				</Suspense>

		);
	}
}
<|endoftext|>


<commit_before>import VirtualTree from "./virtual-tree";
import getParameters from "./utils/get-parameters";
import validateParameter from "./utils/validate-parameter";

export default function parametricSVG (root, parameters={}) {
  let tree, svgRoot, element;

  let parsedParameters = {};
  for (let parameter in parameters) if (parameters.hasOwnProperty(parameter)) {
    parsedParameters[parameter] = validateParameter(parameters[parameter]);
    }

   /**
    * Parse and render all elements within the `svgRoot`. Defaults set with `<ref>` elements
    * will be used for calculation, unless you override them with `parameters`.
    *
    * @param  {SVGSVGElement}  svgRoot
    *   An `<svg>` element.
    *
    * @param  {Object}  [parameters]
    *   A hash of additional parameters. They'll extend and override defaults set with `<ref>`
    *   elements.
    *
    * @returns {VirtualTree}
    *   A cached virtual DOM tree for lightning-fast redraws.
    *
    * @function parametricSVG
    */
  if ((svgRoot = root) instanceof SVGSVGElement) {
    tree = new VirtualTree
      ( Array.from(svgRoot.childNodes)
      , { _parameters: Object.assign
          ( getParameters(svgRoot)
          , parsedParameters
          )
        }
      );
    }

   /**
    * Pass any SVG node (like `<circle>`) to parse and render the node and all its descendants.
    *
    * @param  {SVGElement}  element
    *
    * @param  {Object}  parameters
    *   A hash of parameters.
    *
    * @returns {VirtualTree}
    *   A cached virtual DOM tree for lightning-fast redraws.
    *
    * @function parametricSVG
    */
  else if ((element = root) instanceof SVGElement) {
    tree = new VirtualTree
      ( [element]
      , {_parameters: parsedParameters}
      );
    }

   /**
    * Pass a cached `VirtualTree` to render the tree without reparsing any DOM. This is the fastest
    * option.
    *
    * @param  {VirtualTree}  virtualTree
    *
    * @param  {Object}  [parameters]
    *   Supply a hash of additional parameters. They'll extend and replace cached ones.
    *
    * @returns {VirtualTree}
    *   A cached virtual DOM tree for lightning-fast redraws.
    *
    * @function parametricSVG
    */
  else if (!((tree = root) instanceof VirtualTree)) throw new TypeError("parametricSVG: "
    + "The first argument must be an `SVGSVGElement`, `SVGElement`, or `VirtualTree`."
    );

  return tree._render();
  }
<commit_msg>Polish the API<commit_after>import VirtualTree from "./virtual-tree";
import getParameters from "./utils/get-parameters";
import validateParameter from "./utils/validate-parameter";

export default function parametricSVG (root, parameters={}) {
  let tree, svgRoot, element;

  if (!parameters || typeof parameters != "object") throw new TypeError("parametricSVG: "
    + "If you pass `parameters`, it must be an object."
    );
  let parsedParameters = {};
  for (let parameter in parameters) if (parameters.hasOwnProperty(parameter)) {
    parsedParameters[parameter] = validateParameter(parameters[parameter]);
    }

   /**
    * Parse and render all elements within the `svgRoot`. Defaults set with `<ref>` elements
    * will be used for calculation, unless you override them with `parameters`.
    *
    * @param  {SVGSVGElement}  svgRoot
    *   An `<svg>` element.
    *
    * @param  {Object}  [parameters]
    *   A hash of additional parameters. They'll extend and override defaults set with `<ref>`
    *   elements.
    *
    * @returns {VirtualTree}
    *   A cached virtual DOM tree for lightning-fast redraws.
    *
    * @function parametricSVG
    */
  if ((svgRoot = root) instanceof SVGSVGElement) {
    tree = new VirtualTree
      ( Array.from(svgRoot.childNodes)
      , { _parameters: Object.assign
          ( getParameters(svgRoot)
          , parsedParameters
          )
        }
      );
    }

   /**
    * Pass any SVG node (like `<circle>`) to parse and render the node and all its descendants.
    *
    * @param  {SVGElement}  element
    *
    * @param  {Object}  parameters
    *   A hash of parameters.
    *
    * @returns {VirtualTree}
    *   A cached virtual DOM tree for lightning-fast redraws.
    *
    * @function parametricSVG
    */
  else if ((element = root) instanceof SVGElement) {
    tree = new VirtualTree
      ( [element]
      , {_parameters: parsedParameters}
      );
    }

   /**
    * Pass a cached `VirtualTree` to render the tree without reparsing any DOM. This is the fastest
    * option.
    *
    * @param  {VirtualTree}  virtualTree
    *
    * @param  {Object}  [parameters]
    *   Supply a hash of additional parameters. They'll extend and replace cached ones.
    *
    * @returns {VirtualTree}
    *   A cached virtual DOM tree for lightning-fast redraws.
    *
    * @function parametricSVG
    */
  else if (((tree = root) instanceof VirtualTree)) {
    Object.assign(tree._parameters, parsedParameters);
    }

  else throw new TypeError("parametricSVG: "
    + "The first argument must be an `SVGSVGElement`, `SVGElement`, or `VirtualTree`."
    );

  return tree._render();
  }
<|endoftext|>