<commit_before>/*
 * Copyright 2005 Shinya Kasatani
 *
 * 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.
 */

//
// overlay functions for the browser.
//

SeleniumIDE.Overlay = {};

SeleniumIDE.Overlay.NUM_RECENT_COMMANDS = 8;

SeleniumIDE.Overlay.appendCheck = function(event) {
	var command = event.target._Selenium_IDE_command;
	if (command.command.match(/^store/)) {
		command[command.valueProperty] = window.prompt(SeleniumIDE.Overlay.getString("askForVariableName"));
	}
	SeleniumIDE.Loader.getTopEditor().addCommand(command.command, command.target, command.value, command.window);
	SeleniumIDE.Overlay.addRecentCommand(command.command);
}

SeleniumIDE.Overlay.getRecentCommands = function() {
	if (SeleniumIDE.Preferences.branch.prefHasUserValue("recentCommands")) {
		var recentCommands = SeleniumIDE.Preferences.getString("recentCommands");
		return recentCommands.split(/,/);
	} else {
		return ['open', 'verifyTextPresent', 'verifyValue'];
	}
}

SeleniumIDE.Overlay.getString = function(key) {
    return window.document.getElementById("selenium-ide-strings").getString(key);
}

SeleniumIDE.Overlay.addRecentCommand = function(id) {
	var checks = this.getRecentCommands();
	var n = checks.indexOf(id);
	if (n >= 0) {
		checks.splice(n, 1);
	}
	checks.unshift(id);
	if (checks.length > this.NUM_RECENT_COMMANDS) {
		checks.pop();
	}
    SeleniumIDE.Preferences.setString('recentCommands', checks.join(','));
}

SeleniumIDE.Overlay.testRecorderPopup = function(event) {
	var showAll;
	if (event.target.id == "contentAreaContextMenu") {
		showAll = false;
	} else if (event.target.id == "selenium-ide-all-checks") {
		showAll = true;
	} else {
		return;
	}
	var contextMenu = event.target;
	var self = SeleniumIDE.Overlay;

	// remove old menu
	for (var i = contextMenu.childNodes.length - 1; i >= 0; i--) {
		var item = contextMenu.childNodes[i];
		if (item.id && /^selenium-ide-/.test(item.id)) {
			contextMenu.removeChild(item);
		}
	}

	var recorder = SeleniumIDE.Loader.getTopEditor();
	if (recorder) {
		if (!showAll) {
			contextMenu.appendChild(self.createMenuSeparator('recent'));
		}

		var recentCommands = self.getRecentCommands();
		var menuitems;
		var prefixList = ['action', 'assert', 'verify', 'waitFor', 'store'];

		if (showAll) {
			menuitems = {};
			prefixList.forEach(function(prefix) {
					menuitems[prefix] = [];
				});
		} else {
			menuitems = [];
		}

		function items(prefix) {
			return showAll ? menuitems[prefix] : menuitems;
		}

		var CommandBuilders = SeleniumIDE.Loader.getTopEditor().window.CommandBuilders;
		for (var i = 0; i < CommandBuilders.builders.length; i++) {
			var builder = CommandBuilders.builders[i];
			var focusedWindow = contextMenu.ownerDocument.commandDispatcher.focusedWindow;
			var command = CommandBuilders.callBuilder(builder, focusedWindow);

			if (builder.commandType == 'action') {
				command.builder = builder;
				if (showAll || recentCommands.indexOf(command.command) >= 0) {
					items('action').push(self.createCheckMenuItem((showAll ? 'all-' : ''), command));
				}
			} else {
				prefixList.forEach(function(prefix) {
						if ('action' == prefix) return;
						var newCommand = {};
						for (prop in command) {
							newCommand[prop] = command[prop];
						}
						if (prefix == 'store') {
							if (newCommand.booleanAccessor) {
								if (newCommand.target == null) {
									newCommand.valueProperty = 'target';
								} else {
									newCommand.valueProperty = 'value';
								}
							} else {
								if (newCommand.value == null) {
									newCommand.valueProperty = 'target';
								} else {
									newCommand.valueProperty = 'value';
								}
							}
						}
						var accessor = newCommand.accessor.replace(/^[a-z]/, function(str) { return str.toUpperCase() });
						newCommand.command = prefix + accessor;
						newCommand.builder = builder;
						if (showAll || recentCommands.indexOf(newCommand.command) >= 0) {
							items(prefix).push(self.createCheckMenuItem((showAll ? 'all-' : ''), newCommand));
						}
					});
			}
		}
		if (showAll) {
			var first = true;
			prefixList.forEach(function(prefix) {
					if (!first) {
						contextMenu.appendChild(self.createMenuSeparator(prefix));
					}
					menuitems[prefix].forEach(function(item) {
							contextMenu.appendChild(item);
					});
					first = false;
				});
		} else {
			menuitems.forEach(function(item) {
					contextMenu.appendChild(item);
				});
			var menu = document.createElement("menu");
			menu.setAttribute("id", "selenium-ide-all-checks-menu");
			menu.setAttribute("label", self.getString("showAllChecks.label"));
			var popup = document.createElement("menupopup");
			popup.setAttribute("id", "selenium-ide-all-checks");
			contextMenu.appendChild(menu);
			menu.appendChild(popup);
		}
	}
}

SeleniumIDE.Overlay.createMenuSeparator = function(id) {
	var menuitem = document.createElement("menuseparator");
	menuitem.setAttribute("id", "selenium-ide-separator-" + id);
	return menuitem;
}

SeleniumIDE.Overlay.createMenuSeparator = function(id) {
	var menuitem = document.createElement("menuseparator");
	menuitem.setAttribute("id", "selenium-ide-separator-" + id);
	return menuitem;
}

SeleniumIDE.Overlay.createCheckMenuItem = function(idPrefix, command) {
	var menuitem = document.createElement("menuitem");
	menuitem.setAttribute("id", "selenium-ide-check-" + idPrefix + command.command);
	menuitem.setAttribute("disabled", command.disabled ? 'true' : 'false');
	menuitem.setAttribute("label", command.command + ' ' + command.target + ' ' + command.value);
	menuitem._Selenium_IDE_command = command;
	return menuitem;
}

SeleniumIDE.Overlay.onContentLoaded = function(event) {
	var isRootDocument = false;
	var browsers = window.getBrowser().browsers;
	for (var i = 0; i < browsers.length; i++) {
		var cw = browsers[i].contentWindow;
		if (cw && cw.document == event.target) {
			isRootDocument = true;
		}
	}
	//SeleniumIDE.Loader.reloadRecorder(window.getBrowser().contentWindow, isRootDocument);
	SeleniumIDE.Loader.reloadRecorder(event.target.defaultView, isRootDocument);

	var contextMenu = window.document.getElementById("contentAreaContextMenu");
	if (contextMenu) {
		contextMenu.addEventListener("popupshowing", SeleniumIDE.Overlay.testRecorderPopup, false);
		contextMenu.addEventListener("command", SeleniumIDE.Overlay.appendCheck, false);
	}
}

SeleniumIDE.Overlay.onLoad = function(event) {
    var doc = event.originalTarget;
    if (doc.defaultView) {
        doc.defaultView.setTimeout(function() {
                doc.readyState = "complete";
            }, 0);
    }
}

SeleniumIDE.Overlay.init = function() {
	var appcontent = window.document.getElementById("appcontent");
	if (appcontent) {
		appcontent.addEventListener("DOMContentLoaded", SeleniumIDE.Overlay.onContentLoaded, false);
        appcontent.addEventListener("load", SeleniumIDE.Overlay.onLoad, true);
	}
	window.addEventListener("beforeunload",
							function(event) {
								SeleniumIDE.Loader.getEditors().forEach(function(editor) {
										var doc;
										if (event.target.nodeType == 9) { // DOCUMENT_NODE
											doc = event.target;
										} else {
											doc = event.target.ownerDocument;
										}
										editor.onUnloadDocument(doc);
									});
							}, false);
}

SeleniumIDE.Overlay.init();
<commit_msg>avoid exception<commit_after>/*
 * Copyright 2005 Shinya Kasatani
 *
 * 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.
 */

//
// overlay functions for the browser.
//

SeleniumIDE.Overlay = {};

SeleniumIDE.Overlay.NUM_RECENT_COMMANDS = 8;

SeleniumIDE.Overlay.appendCheck = function(event) {
	var command = event.target._Selenium_IDE_command;
    if (command) {
        if (command.command.match(/^store/)) {
            command[command.valueProperty] = window.prompt(SeleniumIDE.Overlay.getString("askForVariableName"));
        }
        SeleniumIDE.Loader.getTopEditor().addCommand(command.command, command.target, command.value, command.window);
        SeleniumIDE.Overlay.addRecentCommand(command.command);
    }
}

SeleniumIDE.Overlay.getRecentCommands = function() {
	if (SeleniumIDE.Preferences.branch.prefHasUserValue("recentCommands")) {
		var recentCommands = SeleniumIDE.Preferences.getString("recentCommands");
		return recentCommands.split(/,/);
	} else {
		return ['open', 'verifyTextPresent', 'verifyValue'];
	}
}

SeleniumIDE.Overlay.getString = function(key) {
    return window.document.getElementById("selenium-ide-strings").getString(key);
}

SeleniumIDE.Overlay.addRecentCommand = function(id) {
	var checks = this.getRecentCommands();
	var n = checks.indexOf(id);
	if (n >= 0) {
		checks.splice(n, 1);
	}
	checks.unshift(id);
	if (checks.length > this.NUM_RECENT_COMMANDS) {
		checks.pop();
	}
    SeleniumIDE.Preferences.setString('recentCommands', checks.join(','));
}

SeleniumIDE.Overlay.testRecorderPopup = function(event) {
	var showAll;
	if (event.target.id == "contentAreaContextMenu") {
		showAll = false;
	} else if (event.target.id == "selenium-ide-all-checks") {
		showAll = true;
	} else {
		return;
	}
	var contextMenu = event.target;
	var self = SeleniumIDE.Overlay;

	// remove old menu
	for (var i = contextMenu.childNodes.length - 1; i >= 0; i--) {
		var item = contextMenu.childNodes[i];
		if (item.id && /^selenium-ide-/.test(item.id)) {
			contextMenu.removeChild(item);
		}
	}

	var recorder = SeleniumIDE.Loader.getTopEditor();
	if (recorder) {
		if (!showAll) {
			contextMenu.appendChild(self.createMenuSeparator('recent'));
		}

		var recentCommands = self.getRecentCommands();
		var menuitems;
		var prefixList = ['action', 'assert', 'verify', 'waitFor', 'store'];

		if (showAll) {
			menuitems = {};
			prefixList.forEach(function(prefix) {
					menuitems[prefix] = [];
				});
		} else {
			menuitems = [];
		}

		function items(prefix) {
			return showAll ? menuitems[prefix] : menuitems;
		}

		var CommandBuilders = SeleniumIDE.Loader.getTopEditor().window.CommandBuilders;
		for (var i = 0; i < CommandBuilders.builders.length; i++) {
			var builder = CommandBuilders.builders[i];
			var focusedWindow = contextMenu.ownerDocument.commandDispatcher.focusedWindow;
			var command = CommandBuilders.callBuilder(builder, focusedWindow);

			if (builder.commandType == 'action') {
				command.builder = builder;
				if (showAll || recentCommands.indexOf(command.command) >= 0) {
					items('action').push(self.createCheckMenuItem((showAll ? 'all-' : ''), command));
				}
			} else {
				prefixList.forEach(function(prefix) {
						if ('action' == prefix) return;
						var newCommand = {};
						for (prop in command) {
							newCommand[prop] = command[prop];
						}
						if (prefix == 'store') {
							if (newCommand.booleanAccessor) {
								if (newCommand.target == null) {
									newCommand.valueProperty = 'target';
								} else {
									newCommand.valueProperty = 'value';
								}
							} else {
								if (newCommand.value == null) {
									newCommand.valueProperty = 'target';
								} else {
									newCommand.valueProperty = 'value';
								}
							}
						}
						var accessor = newCommand.accessor.replace(/^[a-z]/, function(str) { return str.toUpperCase() });
						newCommand.command = prefix + accessor;
						newCommand.builder = builder;
						if (showAll || recentCommands.indexOf(newCommand.command) >= 0) {
							items(prefix).push(self.createCheckMenuItem((showAll ? 'all-' : ''), newCommand));
						}
					});
			}
		}
		if (showAll) {
			var first = true;
			prefixList.forEach(function(prefix) {
					if (!first) {
						contextMenu.appendChild(self.createMenuSeparator(prefix));
					}
					menuitems[prefix].forEach(function(item) {
							contextMenu.appendChild(item);
					});
					first = false;
				});
		} else {
			menuitems.forEach(function(item) {
					contextMenu.appendChild(item);
				});
			var menu = document.createElement("menu");
			menu.setAttribute("id", "selenium-ide-all-checks-menu");
			menu.setAttribute("label", self.getString("showAllChecks.label"));
			var popup = document.createElement("menupopup");
			popup.setAttribute("id", "selenium-ide-all-checks");
			contextMenu.appendChild(menu);
			menu.appendChild(popup);
		}
	}
}

SeleniumIDE.Overlay.createMenuSeparator = function(id) {
	var menuitem = document.createElement("menuseparator");
	menuitem.setAttribute("id", "selenium-ide-separator-" + id);
	return menuitem;
}

SeleniumIDE.Overlay.createMenuSeparator = function(id) {
	var menuitem = document.createElement("menuseparator");
	menuitem.setAttribute("id", "selenium-ide-separator-" + id);
	return menuitem;
}

SeleniumIDE.Overlay.createCheckMenuItem = function(idPrefix, command) {
	var menuitem = document.createElement("menuitem");
	menuitem.setAttribute("id", "selenium-ide-check-" + idPrefix + command.command);
	menuitem.setAttribute("disabled", command.disabled ? 'true' : 'false');
	menuitem.setAttribute("label", command.command + ' ' + command.target + ' ' + command.value);
	menuitem._Selenium_IDE_command = command;
	return menuitem;
}

SeleniumIDE.Overlay.onContentLoaded = function(event) {
	var isRootDocument = false;
	var browsers = window.getBrowser().browsers;
	for (var i = 0; i < browsers.length; i++) {
		var cw = browsers[i].contentWindow;
		if (cw && cw.document == event.target) {
			isRootDocument = true;
		}
	}
	//SeleniumIDE.Loader.reloadRecorder(window.getBrowser().contentWindow, isRootDocument);
	SeleniumIDE.Loader.reloadRecorder(event.target.defaultView, isRootDocument);

	var contextMenu = window.document.getElementById("contentAreaContextMenu");
	if (contextMenu) {
		contextMenu.addEventListener("popupshowing", SeleniumIDE.Overlay.testRecorderPopup, false);
		contextMenu.addEventListener("command", SeleniumIDE.Overlay.appendCheck, false);
	}
}

SeleniumIDE.Overlay.onLoad = function(event) {
    var doc = event.originalTarget;
    if (doc.defaultView) {
        doc.defaultView.setTimeout(function() {
                doc.readyState = "complete";
            }, 0);
    }
}

SeleniumIDE.Overlay.init = function() {
	var appcontent = window.document.getElementById("appcontent");
	if (appcontent) {
		appcontent.addEventListener("DOMContentLoaded", SeleniumIDE.Overlay.onContentLoaded, false);
        appcontent.addEventListener("load", SeleniumIDE.Overlay.onLoad, true);
	}
	window.addEventListener("beforeunload",
							function(event) {
								SeleniumIDE.Loader.getEditors().forEach(function(editor) {
										var doc;
										if (event.target.nodeType == 9) { // DOCUMENT_NODE
											doc = event.target;
										} else {
											doc = event.target.ownerDocument;
										}
										editor.onUnloadDocument(doc);
									});
							}, false);
}

SeleniumIDE.Overlay.init();
<|endoftext|>


<commit_before>/**
 * Copyright 2017 The AMP HTML Authors. All Rights Reserved.
 *
 * 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 {isLayoutSizeDefined} from '../../../src/layout';
import {tryParseJson} from '../../../src/json';
import {user} from '../../../src/log';
import {removeElement} from '../../../src/dom';
import {
  installVideoManagerForDoc,
} from '../../../src/service/video-manager-impl';
import {isObject} from '../../../src/types';
import {listen} from '../../../src/event-helper';
import {VideoEvents} from '../../../src/video-interface';
import {videoManagerForDoc} from '../../../src/services';

/**
 * @implements {../../../src/video-interface.VideoInterface}
 */
class Amp3QPlayer extends AMP.BaseElement {

  /** @param {!AmpElement} element */
  constructor(element) {
    super(element);

    /** @private {?Element} */
    this.iframe_ = null;

    /** @private {?Function} */
    this.unlistenMessage_ = null;

    /** @private {?Promise} */
    this.playerReadyPromise_ = null;

    /** @private {?Function} */
    this.playerReadyResolver_ = null;
  }

  /**
   * @param {boolean=} opt_onLayout
   * @override
   */
  preconnectCallback(opt_onLayout) {
    this.preconnect.url('https://playout.3qsdn.com', opt_onLayout);
  }

  /** @override */
  buildCallback() {
    this.playerReadyPromise_ = new Promise(resolve => {
      this.playerReadyResolver_ = resolve;
    });

    installVideoManagerForDoc(this.element);
    videoManagerForDoc(this.element).register(this);
  }

  /** @override */
  layoutCallback() {
    const dataId = user().assert(
        this.element.getAttribute('data-id'),
        'The data-id attribute is required for <amp-3q-player> %s',
        this.element);

    const iframe = this.element.ownerDocument.createElement('iframe');
    iframe.setAttribute('frameborder', '0');
    iframe.setAttribute('allowfullscreen', 'true');
    this.applyFillContent(iframe, true);
    iframe.src = 'https://playout.3qsdn.com/' +
        encodeURIComponent(dataId) + '?autoplay=true&amp=true';
    this.element.appendChild(iframe);

    this.iframe_ = iframe;

    this.unlistenMessage_ = listen(
      this.win,
      'message',
      this.sdnBridge_.bind(this)
    );

    return this.loadPromise(this.iframe_).then(() => {
      this.playerReadyResolver_();
      this.element.dispatchCustomEvent(VideoEvents.LOAD);
    });
  }

  /** @override */
  unlayoutCallback() {
    if (this.iframe_) {
      removeElement(this.iframe_);
      this.iframe_ = null;
    }
    if (this.unlistenMessage_) {
      this.unlistenMessage_();
    }
    return true;
  }

  /** @override */
  isLayoutSupported(layout) {
    return isLayoutSizeDefined(layout);
  }

  /** @override */
  viewportCallback(visible) {
    this.element.dispatchCustomEvent(VideoEvents.VISIBILITY, {visible});
  }

  /** @override */
  pauseCallback() {
    if (this.iframe_) {
      this.pause();
    }
  }

  sdnBridge_(event) {
    if (event.source) {
      if (event.source != this.iframe_.contentWindow) {
        return;
      }
    }

    const data = isObject(event.data) ? event.data : tryParseJson(event.data);
    if (data === undefined) {
      return;
    }

    switch (data.data) {
      case 'playing':
        this.element.dispatchCustomEvent(VideoEvents.PLAY);
        break;
      case 'paused':
        this.element.dispatchCustomEvent(VideoEvents.PAUSE);
        break;
      case 'muted':
        this.element.dispatchCustomEvent(VideoEvents.MUTED);
        break;
      case 'unmuted':
        this.element.dispatchCustomEvent(VideoEvents.UNMUTED);
        break;
    }
  }

  sdnPostMessage_(message) {
    this.playerReadyPromise_.then(() => {
      if (this.iframe_ && this.iframe_.contentWindow) {
        this.iframe_.contentWindow./*OK*/postMessage(message, '*');
      }
    });
  }

  // VideoInterface Implementation. See ../src/video-interface.VideoInterface

  /** @override */
  play() {
    this.sdnPostMessage_('play2');
  }

  /** @override */
  pause() {
    this.sdnPostMessage_('pause');
  }

  /** @override */
  mute() {
    this.sdnPostMessage_('mute');
  }

  /** @override */
  unmute() {
    this.sdnPostMessage_('unmute');
  }

  /** @override */
  supportsPlatform() {
    return true;
  }

  /** @override */
  isInteractive() {
    return true;
  }

  /** @override */
  showControls() {
    this.sdnPostMessage_('showControlbar');
  }

  /** @override */
  hideControls() {
    this.sdnPostMessage_('hideControlbar');
  }
};

AMP.registerElement('amp-3q-player', Amp3QPlayer);
<commit_msg>Waiting for Player Ready Event #7999<commit_after>/**
 * Copyright 2017 The AMP HTML Authors. All Rights Reserved.
 *
 * 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 {isLayoutSizeDefined} from '../../../src/layout';
import {tryParseJson} from '../../../src/json';
import {user} from '../../../src/log';
import {removeElement} from '../../../src/dom';
import {
  installVideoManagerForDoc,
} from '../../../src/service/video-manager-impl';
import {isObject} from '../../../src/types';
import {listen} from '../../../src/event-helper';
import {VideoEvents} from '../../../src/video-interface';
import {videoManagerForDoc} from '../../../src/services';

/**
 * @implements {../../../src/video-interface.VideoInterface}
 */
class Amp3QPlayer extends AMP.BaseElement {

  /** @param {!AmpElement} element */
  constructor(element) {
    super(element);

    /** @private {?Element} */
    this.iframe_ = null;

    /** @private {?Function} */
    this.unlistenMessage_ = null;

    /** @private {?Promise} */
    this.playerReadyPromise_ = null;

    /** @private {?Function} */
    this.playerReadyResolver_ = null;
  }

  /**
   * @param {boolean=} opt_onLayout
   * @override
   */
  preconnectCallback(opt_onLayout) {
    this.preconnect.url('https://playout.3qsdn.com', opt_onLayout);
  }

  /** @override */
  buildCallback() {
    this.playerReadyPromise_ = new Promise(resolve => {
      this.playerReadyResolver_ = resolve;
    });

    installVideoManagerForDoc(this.element);
    videoManagerForDoc(this.element).register(this);
  }

  /** @override */
  layoutCallback() {
    const dataId = user().assert(
        this.element.getAttribute('data-id'),
        'The data-id attribute is required for <amp-3q-player> %s',
        this.element);

    const iframe = this.element.ownerDocument.createElement('iframe');
    iframe.setAttribute('frameborder', '0');
    iframe.setAttribute('allowfullscreen', 'true');
    this.applyFillContent(iframe, true);
    iframe.src = 'https://playout.3qsdn.com/' +
        encodeURIComponent(dataId) + '?autoplay=true&amp=true';
    this.element.appendChild(iframe);

    this.iframe_ = iframe;

    this.unlistenMessage_ = listen(
      this.win,
      'message',
      this.sdnBridge_.bind(this)
    );

    return this.loadPromise(this.iframe_);
  }

  /** @override */
  unlayoutCallback() {
    if (this.iframe_) {
      removeElement(this.iframe_);
      this.iframe_ = null;
    }
    if (this.unlistenMessage_) {
      this.unlistenMessage_();
    }
    return true;
  }

  /** @override */
  isLayoutSupported(layout) {
    return isLayoutSizeDefined(layout);
  }

  /** @override */
  viewportCallback(visible) {
    this.element.dispatchCustomEvent(VideoEvents.VISIBILITY, {visible});
  }

  /** @override */
  pauseCallback() {
    if (this.iframe_) {
      this.pause();
    }
  }

  sdnBridge_(event) {
    if (event.source) {
      if (event.source != this.iframe_.contentWindow) {
        return;
      }
    }

    const data = isObject(event.data) ? event.data : tryParseJson(event.data);
    if (data === undefined) {
      return;
    }

    console.log(data.data);

    switch (data.data) {
      case 'ready':
        this.element.dispatchCustomEvent(VideoEvents.LOAD);
          this.playerReadyResolver_();
        break;
      case 'playing':
        this.element.dispatchCustomEvent(VideoEvents.PLAY);
        break;
      case 'paused':
        this.element.dispatchCustomEvent(VideoEvents.PAUSE);
        break;
      case 'muted':
        this.element.dispatchCustomEvent(VideoEvents.MUTED);
        break;
      case 'unmuted':
        this.element.dispatchCustomEvent(VideoEvents.UNMUTED);
        break;
    }
  }

  sdnPostMessage_(message) {
    this.playerReadyPromise_.then(() => {
      if (this.iframe_ && this.iframe_.contentWindow) {
        this.iframe_.contentWindow./*OK*/postMessage(message, '*');
      }
    });
  }

  // VideoInterface Implementation. See ../src/video-interface.VideoInterface

  /** @override */
  play() {
    this.sdnPostMessage_('play2');
  }

  /** @override */
  pause() {
    this.sdnPostMessage_('pause');
  }

  /** @override */
  mute() {
    this.sdnPostMessage_('mute');
  }

  /** @override */
  unmute() {
    this.sdnPostMessage_('unmute');
  }

  /** @override */
  supportsPlatform() {
    return true;
  }

  /** @override */
  isInteractive() {
    return true;
  }

  /** @override */
  showControls() {
    this.sdnPostMessage_('showControlbar');
  }

  /** @override */
  hideControls() {
    this.sdnPostMessage_('hideControlbar');
  }
};

AMP.registerElement('amp-3q-player', Amp3QPlayer);
<|endoftext|>


<commit_before>/**
 * Copyright 2018 The AMP HTML Authors. All Rights Reserved.
 *
 * 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 {AmpEvents} from '../../../src/amp-events';
import {TextMask} from './text-mask';
import {iterateCursor} from '../../../src/dom';
import {listen} from '../../../src/event-helper';

const SERVICE = 'inputmask';
const TAG = `amp-${SERVICE}`;

export class AmpInputmaskService {
  /**
   * @param {!../../../src/service/ampdoc-impl.AmpDoc} ampdoc
   */
  constructor(ampdoc) {
    this.ampdoc = ampdoc;

    /** @private {!Array<!TextMask>} */
    this.masks_ = [];

    /** @const */
    this.domUpdateUnlistener_ = listen(
      this.ampdoc.getRootNode(),
      AmpEvents.DOM_UPDATE,
      () => this.install()
    );
  }

  /**
   * Install the inputmask service and controllers.
   */
  install() {
    const maskElements = this.ampdoc.getRootNode().querySelectorAll('[mask]');
    iterateCursor(maskElements, (element) => {
      if (TextMask.isMasked(element)) {
        return;
      }
      const tm = new TextMask(element);
      this.masks_.push(tm);
    });
  }

  /**
   * Remove the inpumask service and controllers.
   */
  uninstall() {
    this.domUpdateUnlistener_();
    this.masks_.forEach((m) => m.dispose());
    this.masks_ = [];
  }
}

AMP.extension(TAG, '0.1', function (AMP) {
  AMP.registerServiceForDoc(SERVICE, function (ampdoc) {
    return new AmpInputmaskService(ampdoc);
  });
});
<commit_msg>🐛  amp-inputmask: query is too zealous (#29624)<commit_after>/**
 * Copyright 2018 The AMP HTML Authors. All Rights Reserved.
 *
 * 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 {AmpEvents} from '../../../src/amp-events';
import {TextMask} from './text-mask';
import {iterateCursor} from '../../../src/dom';
import {listen} from '../../../src/event-helper';

const SERVICE = 'inputmask';
const TAG = `amp-${SERVICE}`;

export class AmpInputmaskService {
  /**
   * @param {!../../../src/service/ampdoc-impl.AmpDoc} ampdoc
   */
  constructor(ampdoc) {
    this.ampdoc = ampdoc;

    /** @private {!Array<!TextMask>} */
    this.masks_ = [];

    /** @const */
    this.domUpdateUnlistener_ = listen(
      this.ampdoc.getRootNode(),
      AmpEvents.DOM_UPDATE,
      () => this.install()
    );
  }

  /**
   * Install the inputmask service and controllers.
   */
  install() {
    const maskElements = this.ampdoc
      .getRootNode()
      .querySelectorAll('input[mask]');
    iterateCursor(maskElements, (element) => {
      if (TextMask.isMasked(element)) {
        return;
      }
      const tm = new TextMask(element);
      this.masks_.push(tm);
    });
  }

  /**
   * Remove the inpumask service and controllers.
   */
  uninstall() {
    this.domUpdateUnlistener_();
    this.masks_.forEach((m) => m.dispose());
    this.masks_ = [];
  }
}

AMP.extension(TAG, '0.1', function (AMP) {
  AMP.registerServiceForDoc(SERVICE, function (ampdoc) {
    return new AmpInputmaskService(ampdoc);
  });
});
<|endoftext|>


<commit_before>function Muppet(age, hobby) {
  this.age = age;
  this.hobby = hobby;

  this.answerNanny = function(){
	return "Everything's cool!";
  }
}

function SwedishChef(age, hobby, mood) {
  Muppet.call(this, age, hobby);
  this.mood = mood;

  this.cook = function() {
    return "Mmmm soup!";
  }
}

SwedishChef.prototype = new Muppet();

describe("About inheritance", function() {
  beforeEach(function(){
    this.muppet = new Muppet(2, "coding");
  	this.swedishChef = new SwedishChef(2, "cooking", "chillin");
  });

  it("should be able to call a method on the derived object", function() {
    expect(this.swedishChef.cook()).toEqual(FILL_ME_IN);
  });

  it("should be able to call a method on the base object", function() {
    expect(this.swedishChef.answerNanny()).toEqual(FILL_ME_IN);
  });

  it("should set constructor parameters on the base object", function() {
    expect(this.swedishChef.age).toEqual(FILL_ME_IN);
    expect(this.swedishChef.hobby).toEqual(FILL_ME_IN);
  });

  it("should set constructor parameters on the derived object", function() {
    expect(this.swedishChef.mood).toEqual(FILL_ME_IN);
  });
});

// http://javascript.crockford.com/prototypal.html
Object.prototype.beget = function () {
  function F() {}
  F.prototype = this;
  return new F();
}

function Gonzo(age, hobby, trick) {
  Muppet.call(this, age, hobby);
  this.trick = trick;

  this.doTrick = function() {
    return this.trick;
  }
}

//no longer need to call the Muppet (base type) constructor
Gonzo.prototype = Muppet.prototype.beget();
//note: if you're wondering how this line affects the below tests, the answer is that it doesn't.
//however, it does do something interesting -- it makes this work:
//  var g = new Gonzo(...);
//  g instanceOf Muppet //true

describe("About Crockford's inheritance improvement", function() {
  beforeEach(function(){
    this.gonzo = new Gonzo(3, "daredevil performer", "eat a tire");
  });

  it("should be able to call a method on the derived object", function() {
    expect(this.gonzo.doTrick()).toEqual(FILL_ME_IN);
  });

  it("should be able to call a method on the base object", function() {
    expect(this.gonzo.answerNanny()).toEqual(FILL_ME_IN);
  });

  it("should set constructor parameters on the base object", function() {
    expect(this.gonzo.age).toEqual(FILL_ME_IN);
    expect(this.gonzo.hobby).toEqual(FILL_ME_IN);
  });

  it("should set constructor parameters on the derived object", function() {
    expect(this.gonzo.trick).toEqual(FILL_ME_IN);
  });
});
<commit_msg>Thinking About Inheritance now passes all 8 tests<commit_after>function Muppet(age, hobby) {
  this.age = age;
  this.hobby = hobby;

  this.answerNanny = function(){
	return "Everything's cool!";
  }
}

function SwedishChef(age, hobby, mood) {
  Muppet.call(this, age, hobby);
  this.mood = mood;

  this.cook = function() {
    return "Mmmm soup!";
  }
}

SwedishChef.prototype = new Muppet();

describe("About inheritance", function() {
  beforeEach(function(){
    this.muppet = new Muppet(2, "coding");
  	this.swedishChef = new SwedishChef(2, "cooking", "chillin");
  });

  it("should be able to call a method on the derived object", function() {
    expect(this.swedishChef.cook()).toEqual("Mmmm soup!");
  });

  it("should be able to call a method on the base object", function() {
    expect(this.swedishChef.answerNanny()).toEqual("Everything's cool!");
  });

  it("should set constructor parameters on the base object", function() {
    expect(this.swedishChef.age).toEqual(2);
    expect(this.swedishChef.hobby).toEqual("cooking");
  });

  it("should set constructor parameters on the derived object", function() {
    expect(this.swedishChef.mood).toEqual("chillin");
  });
});

// http://javascript.crockford.com/prototypal.html
Object.prototype.beget = function () {
  function F() {}
  F.prototype = this;
  return new F();
}

function Gonzo(age, hobby, trick) {
  Muppet.call(this, age, hobby);
  this.trick = trick;

  this.doTrick = function() {
    return this.trick;
  }
}

//no longer need to call the Muppet (base type) constructor
Gonzo.prototype = Muppet.prototype.beget();
//note: if you're wondering how this line affects the below tests, the answer is that it doesn't.
//however, it does do something interesting -- it makes this work:
//  var g = new Gonzo(...);
//  g instanceOf Muppet //true

describe("About Crockford's inheritance improvement", function() {
  beforeEach(function(){
    this.gonzo = new Gonzo(3, ""daredevil performer"", "eat a tire");
  });

  it("should be able to call a method on the derived object", function() {
    expect(this.gonzo.doTrick()).toEqual("eat a tire");
  });

  it("should be able to call a method on the base object", function() {
    expect(this.gonzo.answerNanny()).toEqual("Everything's cool!");
  });

  it("should set constructor parameters on the base object", function() {
    expect(this.gonzo.age).toEqual(3);
    expect(this.gonzo.hobby).toEqual("daredevil performer");
  });

  it("should set constructor parameters on the derived object", function() {
    expect(this.gonzo.trick).toEqual("eat a tire");
  });
});
<|endoftext|>


<commit_before>window.facebookActivityRemover || (window.facebookActivityRemover = {});

remover = facebookActivityRemover
remover.elementIdentifier = {
  actionContainer:    '_51m- vTop _5ep7',
  activityDeleteForm: 'form[action*=\'/delete\']',
  confirmationLink:   'a[ajaxify*=\'timeline/delete\']'
}

remover.run = function(){
  remover.initializeElements();
  remover.runIntervalDeleteJob();
}

remover.initializeElements = function() {
  elements = document.getElementsByClassName(remover.elementIdentifier.actionContainer);
  for(i = 0; i < elements.length; i++) {
    link = elements[i].children[0].children[1].children[0]
    link.click()
  }
}

remover.getDeleteActivityForm = function(){
  forms = document.querySelectorAll(remover.elementIdentifier.activityDeleteForm);
  return forms
}

remover.submitDeleteActivityForm = function() {
  setTimeout(function () {
    forms = remover.getDeleteActivityForm()
    for(i = 0; i < forms.length; i++) {
      forms[i].children[3].children[1].click();
      console.log(i+" status: delete form submitted")
    }
  }, 2000)
}

remover.runIntervalDeleteJob = function(){
  var i = 0; deleteLinks = remover.deleteLinks();

  var intervalId = setInterval(function () {
      deleteLinks[i].click();
      console.log(i+" status: link clicked")
      i++;
      if (i <= deleteLinks.length) {
         remover.submitDeleteActivityForm(deleteLinks, i)
      }
   }, 2500)
  if(i == deleteLinks.length){clearInterval(intervalId)}
}

remover.deleteLinks = function(){
  return document.querySelectorAll(remover.elementIdentifier.confirmationLink)
}
<commit_msg>update code<commit_after>window.facebookActivityRemover || (window.facebookActivityRemover = {});

remover = facebookActivityRemover
remover.elementIdentifier = {
  actionContainer:    'a[aria-label="Story options"]',
  confirmationLink:   'a[data-feed-option-name="FeedDeleteOption"]'
}

remover.run = function(){
  remover.initializeElements();
  remover.runIntervalDeleteJob();
}

remover.initializeElements = function() {
  console.log("initializeElements")
  elements = document.querySelectorAll(remover.elementIdentifier.actionContainer);
  for (var i = 0; i <= elements.length-1; i++) {
    console.log(i)
    elements[i].click()
  }
}

remover.runIntervalDeleteJob = function(){
  elements = document.querySelectorAll(remover.elementIdentifier.confirmationLink);
  for (var i = 1; i <= elements.length; i++) {
    console.log('runIntervalDeleteJob ' + i);
    (function(index) {
        console.log(index)
        setTimeout(function() { remover.removeAction(index ,elements[index]) }, index * 1000);
    })(i);
  }
}

remover.removeAction = function(idx, element){
  link = elements[idx].click();
  console.log(idx+" delete link clicked")
  setTimeout(function() {
    removeBtn = document.getElementsByClassName('layerConfirm')[0]
    removeBtn.click()
    console.log("confirmation delete link clicked")
  }, idx * 1000);
}<|endoftext|>


<commit_before>
"use strict";

class ItemController {
};

export {ItemController};

<commit_msg>renamed<commit_after>
"use strict";

class UpdateController {
};

export {UpdateController};

<|endoftext|>


<commit_before>/*
Copyright 2015 OpenMarket 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.
*/

'use strict';

// should be atomised
var Loader = require("react-loader");

var MatrixClientPeg = require("../../MatrixClientPeg");

var dis = require("../../dispatcher");

var ComponentBroker = require('../../ComponentBroker');

var Notifier = ComponentBroker.get('organisms/Notifier');

module.exports = {
    getInitialState: function() {
        return {
            logged_in: !!(MatrixClientPeg.get() && MatrixClientPeg.get().credentials),
            ready: false
        };
    },

    componentDidMount: function() {
        this.dispatcherRef = dis.register(this.onAction);
        if (this.state.logged_in) {
            this.startMatrixClient();
        }
        this.focusComposer = false;
        document.addEventListener("keydown", this.onKeyDown);
    },

    componentWillUnmount: function() {
        dis.unregister(this.dispatcherRef);
        document.removeEventListener("keydown", this.onKeyDown);
    },

    componentDidUpdate: function() {
        if (this.focusComposer) {
            dis.dispatch({action: 'focus_composer'});
            this.focusComposer = false;
        }
    },

    onAction: function(payload) {
        var roomIndexDelta = 1;

        switch (payload.action) {
            case 'logout':
                this.setState({
                    logged_in: false,
                    ready: false
                });
                Notifier.stop();
                MatrixClientPeg.get().removeAllListeners();
                MatrixClientPeg.replace(null);
                break;
            case 'view_room':
                this.focusComposer = true;
                this.setState({
                    currentRoom: payload.room_id
                });
                break;
            case 'view_prev_room':
                roomIndexDelta = -1;
            case 'view_next_room':
                var allRooms = MatrixClientPeg.get().getRooms();
                var roomIndex = -1;
                for (var i = 0; i < allRooms.length; ++i) {
                    if (allRooms[i].roomId == this.state.currentRoom) {
                        roomIndex = i;
                        break;
                    }
                }
                roomIndex = (roomIndex + roomIndexDelta) % allRooms.length;
                this.setState({
                    currentRoom: allRooms[roomIndex].roomId
                });
                break;
        }
    },

    onLoggedIn: function() {
        this.setState({logged_in: true});
        this.startMatrixClient();
    },

    startMatrixClient: function() {
        var cli = MatrixClientPeg.get();
        var that = this;
        cli.on('syncComplete', function() {
            var firstRoom = null;
            if (cli.getRooms() && cli.getRooms().length) {
                firstRoom = cli.getRooms()[0].roomId;
            }
            that.setState({ready: true, currentRoom: firstRoom});
            dis.dispatch({action: 'focus_composer'});
        });
        Notifier.start();
        cli.startClient();
    },

    onKeyDown: function(ev) {
        if (ev.altKey) {
            switch (ev.keyCode) {
                case 38:
                    dis.dispatch({action: 'view_prev_room'});
                    ev.stopPropagation();
                    break;
                case 40:
                    dis.dispatch({action: 'view_next_room'});
                    ev.stopPropagation();
                    break;
            }
        }
    }
};

<commit_msg>focus message composer when window gets focus<commit_after>/*
Copyright 2015 OpenMarket 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.
*/

'use strict';

// should be atomised
var Loader = require("react-loader");

var MatrixClientPeg = require("../../MatrixClientPeg");

var dis = require("../../dispatcher");

var ComponentBroker = require('../../ComponentBroker');

var Notifier = ComponentBroker.get('organisms/Notifier');

module.exports = {
    getInitialState: function() {
        return {
            logged_in: !!(MatrixClientPeg.get() && MatrixClientPeg.get().credentials),
            ready: false
        };
    },

    componentDidMount: function() {
        this.dispatcherRef = dis.register(this.onAction);
        if (this.state.logged_in) {
            this.startMatrixClient();
        }
        this.focusComposer = false;
        document.addEventListener("keydown", this.onKeyDown);
        window.addEventListener("focus", this.onFocus);
    },

    componentWillUnmount: function() {
        dis.unregister(this.dispatcherRef);
        document.removeEventListener("keydown", this.onKeyDown);
    },

    componentDidUpdate: function() {
        if (this.focusComposer) {
            dis.dispatch({action: 'focus_composer'});
            this.focusComposer = false;
        }
    },

    onAction: function(payload) {
        var roomIndexDelta = 1;

        switch (payload.action) {
            case 'logout':
                this.setState({
                    logged_in: false,
                    ready: false
                });
                Notifier.stop();
                MatrixClientPeg.get().removeAllListeners();
                MatrixClientPeg.replace(null);
                break;
            case 'view_room':
                this.focusComposer = true;
                this.setState({
                    currentRoom: payload.room_id
                });
                break;
            case 'view_prev_room':
                roomIndexDelta = -1;
            case 'view_next_room':
                var allRooms = MatrixClientPeg.get().getRooms();
                var roomIndex = -1;
                for (var i = 0; i < allRooms.length; ++i) {
                    if (allRooms[i].roomId == this.state.currentRoom) {
                        roomIndex = i;
                        break;
                    }
                }
                roomIndex = (roomIndex + roomIndexDelta) % allRooms.length;
                this.setState({
                    currentRoom: allRooms[roomIndex].roomId
                });
                break;
        }
    },

    onLoggedIn: function() {
        this.setState({logged_in: true});
        this.startMatrixClient();
    },

    startMatrixClient: function() {
        var cli = MatrixClientPeg.get();
        var that = this;
        cli.on('syncComplete', function() {
            var firstRoom = null;
            if (cli.getRooms() && cli.getRooms().length) {
                firstRoom = cli.getRooms()[0].roomId;
            }
            that.setState({ready: true, currentRoom: firstRoom});
            dis.dispatch({action: 'focus_composer'});
        });
        Notifier.start();
        cli.startClient();
    },

    onKeyDown: function(ev) {
        if (ev.altKey) {
            switch (ev.keyCode) {
                case 38:
                    dis.dispatch({action: 'view_prev_room'});
                    ev.stopPropagation();
                    break;
                case 40:
                    dis.dispatch({action: 'view_next_room'});
                    ev.stopPropagation();
                    break;
            }
        }
    },

    onFocus: function(ev) {
        dis.dispatch({action: 'focus_composer'});
    }
};

<|endoftext|>


<commit_before>"use strict";
var CRLF = "\r\n";
var log = require("./log").instance;
var URL=require("url");
var tls = require('tls');
exports.local_request=function local_request(bm,netType){
    var headers;
    var CRLF_index=bm.indexOf(CRLF);
    var http_header_length=bm.indexOf(CRLF+CRLF);
    if(CRLF_index==-1||http_header_length==-1){
        log.debug("not enough request content");
        return null;
    }
    http_header_length+=CRLF.length*2;
    var raw_header=bm.slice(0,http_header_length).toString();
    var content_length=parseInt(getHeader("Content-Length"));

    log.debug("content_length:"+content_length);
    log.debug("http_header_length:"+http_header_length);
    log.debug("bm size:"+bm.size());
    var body="";
    if(typeof(getHeader("Content-Length"))!="undefined"){
        if(content_length+http_header_length<=bm.size()){
            var body=bm.slice(http_header_length,content_length);
            bm.delete(http_header_length+content_length);
        }else{
            return null;
        }
    }else{
        bm.delete(http_header_length);
    }

    function getHeader(name,def){
        if(!headers){
            var header_rest=raw_header.substr(raw_header.indexOf(CRLF)+CRLF.length,http_header_length);
            headers={};
            header_rest.split(CRLF).forEach(function(line){
                if(line){
                    var tmp=line.match(/([^:]*):(.*)/);
                }
                if(tmp){
                    headers[tmp[1].trim()]=tmp[2].trim();
                }
            });
        }
        if(name){
            return headers[name]?headers[name]:def;
        }else{
            return headers;
        }
    }
    return {
        getBody:function(){
            return body;
        },
        getQueryString:(function(){
            var queryStr;
            return function(){
                var tmp;
                if(!queryStr){
                    queryStr=raw_header.substr(0,CRLF_index).split(/\s+/)[1];
                }
                if(tmp=queryStr.match(/^https?:\/\/[^/]*(.*)/)){
                    queryStr=tmp[1];
                }
                if(!queryStr){
                    queryStr="/";
                }
                return queryStr;
            }
        })(),
        getHttpVersion:(function(){
            var version;
            return function(){
                if(!version){
                    version=raw_header.substr(0,CRLF_index).split(/\s+/)[2]=='HTTP/1.0'?"1.0":"1.1";
                }
                return version;
            };
        })(),
        getMethod:(function(){
            var method;
            return function(){
                if(!method){
                    method=raw_header.substr(0,CRLF_index).split(/\s+/)[0];
                }
                return method;
            };
        })(),
        getHeader:getHeader,
        getSendHeader:function(){
            var tmp=[];
            var headers=this.getHeader();
            for(var h in headers){
                tmp.push(h+":"+headers[h]);
            }
            return this.getMethod()+" "+this.getQueryString()+" HTTP/"+this.getHttpVersion()+CRLF+
                tmp.join(CRLF)+CRLF+CRLF;
        },
        getUrl:function(){
            var queryStr=this.getQueryString();
            if(this.getMethod()=='CONNECT'){
                queryStr="http://"+queryStr;
            }
            if(queryStr[0]=='/' && this.getHeader("Host")){
                queryStr=this.getHeader("Host")+queryStr;
                if(netType===tls){
                    queryStr="https://"+queryStr;
                }else{
                    queryStr="http://"+queryStr;
                }
            }
            log.debug(queryStr);
            if(!queryStr){
                log.error(raw_header);
            }
            return URL.parse(queryStr);
        }
    };
}
<commit_msg>update<commit_after>"use strict";
var CRLF = "\r\n";
var log = require("./log").instance;
var URL=require("url");
var tls = require('tls');
exports.local_request=function local_request(bm,netType){
    var headers;
    var CRLF_index=bm.indexOf(CRLF);
    var http_header_length=bm.indexOf(CRLF+CRLF);
    if(CRLF_index==-1||http_header_length==-1){
        log.debug("not enough request content");
        return null;
    }
    http_header_length+=CRLF.length*2;
    var raw_header=bm.slice(0,http_header_length).toString();
    var content_length=parseInt(getHeader("Content-Length"));

    log.debug("content_length:"+content_length);
    log.debug("http_header_length:"+http_header_length);
    log.debug("bm size:"+bm.size());
    var body="";
    if(typeof(getHeader("Content-Length"))!="undefined"){
        if(content_length+http_header_length<=bm.size()){
            var body=bm.slice(http_header_length,content_length);
            bm.delete(http_header_length+content_length);
        }else{
            return null;
        }
    }else{
        bm.delete(http_header_length);
    }

    function getHeader(name,def){
        if(!headers){
            var header_rest=raw_header.substr(raw_header.indexOf(CRLF)+CRLF.length,http_header_length);
            headers={};
            header_rest.split(CRLF).forEach(function(line){
                if(line){
                    var tmp=line.match(/([^:]*):(.*)/);
                }
                if(tmp){
                    headers[tmp[1].trim()]=tmp[2].trim();
                }
            });
        }
        if(name){
            return headers[name]?headers[name]:def;
        }else{
            return headers;
        }
    }
    return {
        getBody:function(){
            return body;
        },
        getQueryString:(function(){
            var queryStr;
            return function(){
                var tmp;
                if(!queryStr){
                    queryStr=raw_header.substr(0,CRLF_index).split(/\s+/)[1];
                }
                if(tmp=queryStr.match(/^https?:\/\/[^/]*(.*)/)){
                    queryStr=tmp[1];
                }
                if(!queryStr){
                    queryStr="/";
                }
                return queryStr;
            }
        })(),
        getHttpVersion:(function(){
            var version;
            return function(){
                if(!version){
                    version=raw_header.substr(0,CRLF_index).split(/\s+/)[2]=='HTTP/1.0'?"1.0":"1.1";
                }
                return version;
            };
        })(),
        getMethod:(function(){
            var method;
            return function(){
                if(!method){
                    method=raw_header.substr(0,CRLF_index).split(/\s+/)[0];
                }
                return method;
            };
        })(),
        getHeader:getHeader,
        getSendHeader:function(){
            var tmp=[];
            var headers=this.getHeader();
            for(var h in headers){
                if(headers.hasOwnProperty(h)){
                    tmp.push(h+":"+headers[h]);
                }
            }
            return this.getMethod()+" "+this.getQueryString()+" HTTP/"+this.getHttpVersion()+CRLF+
                tmp.join(CRLF)+CRLF+CRLF;
        },
        getUrl:function(){
            var queryStr=this.getQueryString();
            if(this.getMethod()=='CONNECT'){
                queryStr="http://"+queryStr;
            }
            if(queryStr[0]=='/' && this.getHeader("Host")){
                queryStr=this.getHeader("Host")+queryStr;
                if(netType===tls){
                    queryStr="https://"+queryStr;
                }else{
                    queryStr="http://"+queryStr;
                }
            }
            log.debug(queryStr);
            if(!queryStr){
                log.error(raw_header);
            }
            return URL.parse(queryStr);
        }
    };
}
<|endoftext|>


<commit_before>"use strict";

var qs    = require('querystring');
var utils = require('./utils');

function createURLFromRequest(request) {
  var url = request.path;
  if (request.query)
    url = url + '?' + qs.stringify(request.query);
  return url;
}

/**
 * Create request from URL
 *
 * @param {String} url
 */
function createRequestFromURL(url) {
  if (url.indexOf('?') > -1) {
    var parts = url.split('?');
    return {
      path: parts[0],
      query: qs.parse(parts[1])
    };
  } else {
    return {
      path: url,
      query: undefined
    };
  }
}

/**
 * Create request from location (such as window.location)
 *
 * @param {Location} loc
 */
function createRequestFromLocation(loc) {
  return {
    path: loc.pathname,
    query: loc.search ? qs.parse(loc.search.slice(1)) : null
  };
}

function normalizeRequest(req) {
  if (utils.isString(req)) {
    req = createRequestFromURL(req);
  } else if (!req) {
    req = createRequestFromLocation(window.location);
  } else if (req && !req.path) {
    var data = req;
    req = createRequestFromLocation(window.location);
    for (var k in data)
      if (k !== 'path' && k !== 'query')
        req[k] = data[k];
  }
  return req;
}

function isEqual(a, b) {
  if (a.path !== b.path)
    return false;

  if (a.query !== b.query)
    return false;

  for (var k in a.query)
    if (a.query[k] !== b.query[k])
      return false;

  for (var k in b.query)
    if (a.query[k] !== b.query[k])
      return false;

  return true;
}

module.exports = {
  isEqual: isEqual,
  normalizeRequest: normalizeRequest,
  createRequestFromURL: createRequestFromURL,
  createRequestFromLocation: createRequestFromLocation,
  createURLFromRequest: createURLFromRequest
};
<commit_msg>Make jshint happy<commit_after>"use strict";

var qs    = require('querystring');
var utils = require('./utils');

function createURLFromRequest(request) {
  var url = request.path;
  if (request.query)
    url = url + '?' + qs.stringify(request.query);
  return url;
}

/**
 * Create request from URL
 *
 * @param {String} url
 */
function createRequestFromURL(url) {
  if (url.indexOf('?') > -1) {
    var parts = url.split('?');
    return {
      path: parts[0],
      query: qs.parse(parts[1])
    };
  } else {
    return {
      path: url,
      query: undefined
    };
  }
}

/**
 * Create request from location (such as window.location)
 *
 * @param {Location} loc
 */
function createRequestFromLocation(loc) {
  return {
    path: loc.pathname,
    query: loc.search ? qs.parse(loc.search.slice(1)) : null
  };
}

function normalizeRequest(req) {
  if (utils.isString(req)) {
    req = createRequestFromURL(req);
  } else if (!req) {
    req = createRequestFromLocation(window.location);
  } else if (req && !req.path) {
    var data = req;
    req = createRequestFromLocation(window.location);
    for (var k in data)
      if (k !== 'path' && k !== 'query')
        req[k] = data[k];
  }
  return req;
}

function isEqual(a, b) {
  if (a.path !== b.path)
    return false;

  if (a.query !== b.query)
    return false;

  var k;

  for (k in a.query)
    if (a.query[k] !== b.query[k])
      return false;

  for (k in b.query)
    if (a.query[k] !== b.query[k])
      return false;

  return true;
}

module.exports = {
  isEqual: isEqual,
  normalizeRequest: normalizeRequest,
  createRequestFromURL: createRequestFromURL,
  createRequestFromLocation: createRequestFromLocation,
  createURLFromRequest: createURLFromRequest
};
<|endoftext|>


<commit_before>/* global requireShared */

const signToken = requireShared("utilities/signToken");

module.exports = (req, res) => {
    if (req.session.redirectUrl) {
        const url = `${req.session.redirectUrl}?accessToken=${signToken(req.user)}`;
        res.redirect(url);
    } else {
        res.status(202).send({accessToken: signToken(req.user)});
    }

    delete req.session.redirectUrl;
    return;
}<commit_msg>Add security so only selected value can be within the accesstoken (_id, email & name)<commit_after>/* global requireShared */

const signToken = requireShared("utilities/signToken");
const {pick} = require("lodash");

module.exports = (req, res) => {

    const user = pick(req.user, ["_id", "email", "name"]);

    if (req.session.redirectUrl) {
        const url = `${req.session.redirectUrl}?accessToken=${signToken(user)}`;
        res.redirect(url);
    } else {
        res.status(202).send({accessToken: signToken(user)});
    }

    delete req.session.redirectUrl;
    return;
}<|endoftext|>


<commit_before>'use strict';

var Shrinkwrap = require('shrinkwrap')
  , Registry = require('npm-registry')
  , readme = require('renderme')
  , moment = require('moment')
  , async = require('async');

//
// Re-use the Github instance from `renderme`.
//
var GitHulk = readme.GitHulk;

/**
* Gather all the required data to correctly render a package page.
*
* @param {String} name The name of the package.
* @param {Object} options Options
* @param {Function} next The callback.
* @api private
*/
function resolve(name, options, next) {
  if ('function' === typeof options) {
    next = options;
    options = {};
  }

  options.registry = options.registry || Registry.mirrors.nodejitsu;
  options.githulk = options.githulk || new GitHulk();

  //
  // Only create a new Registry instance if we've been supplied with a string.
  //
  var npm = 'string' !== typeof options.registry
    ? options.registry
    : new Registry({
      registry: options.registry,
      githulk: options.githulk
  });

  var shrinkwrap = new Shrinkwrap({
    githulk: options.githulk,
    registry: npm
  });

  npm.packages.details(name, function details(err, data) {
    if (err) return next(err);

    data = Array.isArray(data) ? data.pop() : data;

    //
    // Retrieve some additional information and pre-parse some information.
    //
    async.parallel({
      shrinkwrap: function render(next) {
        shrinkwrap.resolve(data, function resolved(err, data, dependent) {
          next(err, dependent);
        });
      },
      readme: function render(next) {
        readme(data, { githulk: options.githulk }, next);
      },
      github: function render(next) {
        var project = options.githulk.project(data);
        if (!project.user || !project.repo) return next();

        options.githulk.repository.get(project.user + '/' + project.repo, next);
      }
    }, function parallel(err, additional) {
      if (err) return next(err);

      reduce({
        package: data,
        readme: additional.readme,
        shrinkwrap: additional.shrinkwrap,
        github: additional.github
      }, next);
    });
  });
}

/**
 * Reduce the massive data structure to something useful.
 *
 * @param {Object} data The received data structure.
 * @param {Function} fn The callback.
 * @api private
 */
function reduce(data, fn) {
  delete data.package.readmeFilename;   // README is already parsed.
  delete data.package.versions;         // Adds to much bloat.
  delete data.package.readme;           // README is already parsed.

  //
  // Remove circular references as it would prevent us from caching in Redis or
  // what ever because there's a circular reference. Keep track of what are main
  // dependencies by providing them with a number, usefull for sorting later on.
  //
  if ('object' === typeof data.shrinkwrap) {
    Object.keys(data.shrinkwrap).forEach(function each(id) {
      data.shrinkwrap[id].main = +(data.shrinkwrap[id].parent.name === data.package.name)

      delete data.shrinkwrap[id].dependencies;
      delete data.shrinkwrap[id].dependent;
      delete data.shrinkwrap[id].parent;
    });
  }

  //
  // Extract github data from array.
  // TODO might need more cleanup
  //
  data.github = data.github.pop();

  //
  // Make sure we default to something so we don't get template errors
  //
  data.readme = data.readme || data.package.description || '';

  //
  // Make all dates human readable.
  //
  if (data.package.time) Object.keys(data.package.time).forEach(function (time) {
    var date = data.package.time[time];

    data.package.time[time] = {
      human: moment(date).format('MMM Do YYYY'),
      ago: moment(date).fromNow(),
      full: date
    };
  });

  ['created', 'modified'].forEach(function (time) {
    var date = data.package[time];

    data.package[time] = {
      human: moment(date).format('MMM Do YYYY'),
      ago: moment(date).fromNow(),
      full: date
    };
  });

  //
  // Transform shrinkwrap to an array and prioritize main dependencies.
  //
  data.shrinkwrap = Object.keys(data.shrinkwrap || {}).map(function wrap(_id) {
    return data.shrinkwrap[_id];
  }).sort(function sort(a, b) {
    return b.main - a.main;
  });

  //
  // Remove empty objects from the package.
  //
  [
    'repository',
    'homepage',
    'bugs'
  ].forEach(function each(key) {
    if (Array.isArray(data.package[key])) {
      if (!data.package[key].length) delete data.package[key];
    } else if ('object' === typeof data.package[key] && !Object.keys(data.package[key]).length) {
      delete data.package[key];
    }
  });

  fn(undefined, data);
}

//
// Expose the methods.
//
resolve.reduce = reduce;
module.exports = resolve;
<commit_msg>[fix] make sure there is always a github object<commit_after>'use strict';

var Shrinkwrap = require('shrinkwrap')
  , Registry = require('npm-registry')
  , readme = require('renderme')
  , moment = require('moment')
  , async = require('async');

//
// Re-use the Github instance from `renderme`.
//
var GitHulk = readme.GitHulk;

/**
* Gather all the required data to correctly render a package page.
*
* @param {String} name The name of the package.
* @param {Object} options Options
* @param {Function} next The callback.
* @api private
*/
function resolve(name, options, next) {
  if ('function' === typeof options) {
    next = options;
    options = {};
  }

  options.registry = options.registry || Registry.mirrors.nodejitsu;
  options.githulk = options.githulk || new GitHulk();

  //
  // Only create a new Registry instance if we've been supplied with a string.
  //
  var npm = 'string' !== typeof options.registry
    ? options.registry
    : new Registry({
      registry: options.registry,
      githulk: options.githulk
  });

  var shrinkwrap = new Shrinkwrap({
    githulk: options.githulk,
    registry: npm
  });

  npm.packages.details(name, function details(err, data) {
    if (err) return next(err);

    data = Array.isArray(data) ? data.pop() : data;

    //
    // Retrieve some additional information and pre-parse some information.
    //
    async.parallel({
      shrinkwrap: function render(next) {
        shrinkwrap.resolve(data, function resolved(err, data, dependent) {
          next(err, dependent);
        });
      },
      readme: function render(next) {
        readme(data, { githulk: options.githulk }, next);
      },
      github: function render(next) {
        var project = options.githulk.project(data);
        if (!project.user || !project.repo) return next();

        options.githulk.repository.get(project.user + '/' + project.repo, next);
      }
    }, function parallel(err, additional) {
      if (err) return next(err);

      reduce({
        package: data,
        readme: additional.readme,
        shrinkwrap: additional.shrinkwrap,
        github: additional.github
      }, next);
    });
  });
}

/**
 * Reduce the massive data structure to something useful.
 *
 * @param {Object} data The received data structure.
 * @param {Function} fn The callback.
 * @api private
 */
function reduce(data, fn) {
  delete data.package.readmeFilename;   // README is already parsed.
  delete data.package.versions;         // Adds to much bloat.
  delete data.package.readme;           // README is already parsed.

  //
  // Remove circular references as it would prevent us from caching in Redis or
  // what ever because there's a circular reference. Keep track of what are main
  // dependencies by providing them with a number, usefull for sorting later on.
  //
  if ('object' === typeof data.shrinkwrap) {
    Object.keys(data.shrinkwrap).forEach(function each(id) {
      data.shrinkwrap[id].main = +(data.shrinkwrap[id].parent.name === data.package.name)

      delete data.shrinkwrap[id].dependencies;
      delete data.shrinkwrap[id].dependent;
      delete data.shrinkwrap[id].parent;
    });
  }

  //
  // Extract github data from array.
  // TODO might need more cleanup
  //
  data.github = (data.github || []).pop() || {};

  //
  // Make sure we default to something so we don't get template errors
  //
  data.readme = data.readme || data.package.description || '';

  //
  // Make all dates human readable.
  //
  if (data.package.time) Object.keys(data.package.time).forEach(function (time) {
    var date = data.package.time[time];

    data.package.time[time] = {
      human: moment(date).format('MMM Do YYYY'),
      ago: moment(date).fromNow(),
      full: date
    };
  });

  ['created', 'modified'].forEach(function (time) {
    var date = data.package[time];

    data.package[time] = {
      human: moment(date).format('MMM Do YYYY'),
      ago: moment(date).fromNow(),
      full: date
    };
  });

  //
  // Transform shrinkwrap to an array and prioritize main dependencies.
  //
  data.shrinkwrap = Object.keys(data.shrinkwrap || {}).map(function wrap(_id) {
    return data.shrinkwrap[_id];
  }).sort(function sort(a, b) {
    return b.main - a.main;
  });

  //
  // Remove empty objects from the package.
  //
  [
    'repository',
    'homepage',
    'bugs'
  ].forEach(function each(key) {
    if (Array.isArray(data.package[key])) {
      if (!data.package[key].length) delete data.package[key];
    } else if ('object' === typeof data.package[key] && !Object.keys(data.package[key]).length) {
      delete data.package[key];
    }
  });

  fn(undefined, data);
}

//
// Expose the methods.
//
resolve.reduce = reduce;
module.exports = resolve;
<|endoftext|>


<commit_before>/* eslint-disable
    camelcase,
    handle-callback-err,
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
/*
 * decaffeinate suggestions:
 * DS101: Remove unnecessary use of Array.from
 * DS102: Remove unnecessary code created because of implicit returns
 * DS207: Consider shorter variations of null checks
 * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
 */
let ProjectPersistenceManager
const UrlCache = require('./UrlCache')
const CompileManager = require('./CompileManager')
const db = require('./db')
const dbQueue = require('./DbQueue')
const async = require('async')
const logger = require('logger-sharelatex')
const oneDay = 24 * 60 * 60 * 1000
const Settings = require('settings-sharelatex')
const diskusage = require('diskusage')
const Metrics = require('./Metrics')

module.exports = ProjectPersistenceManager = {
  EXPIRY_TIMEOUT: Settings.project_cache_length_ms || oneDay * 2.5,

  refreshExpiryTimeout(callback) {
    if (callback == null) {
      callback = function (error) {}
    }
    diskusage.check('/', function (err, stats) {
      if (err) {
        logger.err({ err: err }, 'error getting disk usage')
        return callback(err)
      }
      const lowDisk = stats.available / stats.total < 0.1
      const lowerExpiry = ProjectPersistenceManager.EXPIRY_TIMEOUT * 0.9
      if (lowDisk && Settings.project_cache_length_ms / 2 < lowerExpiry) {
        logger.warn(
          {
            stats: stats,
            newExpiryTimeoutInDays: (lowerExpiry / oneDay).toFixed(2)
          },
          'disk running low on space, modifying EXPIRY_TIMEOUT'
        )
        ProjectPersistenceManager.EXPIRY_TIMEOUT = lowerExpiry
      }
      callback()
    })
  },
  markProjectAsJustAccessed(project_id, callback) {
    if (callback == null) {
      callback = function (error) {}
    }
    const timer = new Metrics.Timer('db-bump-last-accessed')
    const job = (cb) =>
      db.Project.findOrCreate({ where: { project_id } })
        .spread((project, created) =>
          project
            .update({ lastAccessed: new Date() })
            .then(() => cb())
            .error(cb)
        )
        .error(cb)
    dbQueue.queue.push(job, (error) => {
      timer.done()
      callback(error)
    })
  },

  clearExpiredProjects(callback) {
    if (callback == null) {
      callback = function (error) {}
    }
    return ProjectPersistenceManager._findExpiredProjectIds(function (
      error,
      project_ids
    ) {
      if (error != null) {
        return callback(error)
      }
      logger.log({ project_ids }, 'clearing expired projects')
      const jobs = Array.from(project_ids || []).map((project_id) =>
        ((project_id) => (callback) =>
          ProjectPersistenceManager.clearProjectFromCache(project_id, function (
            err
          ) {
            if (err != null) {
              logger.error({ err, project_id }, 'error clearing project')
            }
            return callback()
          }))(project_id)
      )
      return async.series(jobs, function (error) {
        if (error != null) {
          return callback(error)
        }
        return CompileManager.clearExpiredProjects(
          ProjectPersistenceManager.EXPIRY_TIMEOUT,
          (error) => callback()
        )
      })
    })
  }, // ignore any errors from deleting directories

  clearProject(project_id, user_id, callback) {
    if (callback == null) {
      callback = function (error) {}
    }
    logger.log({ project_id, user_id }, 'clearing project for user')
    return CompileManager.clearProject(project_id, user_id, function (error) {
      if (error != null) {
        return callback(error)
      }
      return ProjectPersistenceManager.clearProjectFromCache(
        project_id,
        function (error) {
          if (error != null) {
            return callback(error)
          }
          return callback()
        }
      )
    })
  },

  clearProjectFromCache(project_id, callback) {
    if (callback == null) {
      callback = function (error) {}
    }
    logger.log({ project_id }, 'clearing project from cache')
    return UrlCache.clearProject(project_id, function (error) {
      if (error != null) {
        logger.err({ error, project_id }, 'error clearing project from cache')
        return callback(error)
      }
      return ProjectPersistenceManager._clearProjectFromDatabase(
        project_id,
        function (error) {
          if (error != null) {
            logger.err(
              { error, project_id },
              'error clearing project from database'
            )
          }
          return callback(error)
        }
      )
    })
  },

  _clearProjectFromDatabase(project_id, callback) {
    if (callback == null) {
      callback = function (error) {}
    }
    logger.log({ project_id }, 'clearing project from database')
    const job = (cb) =>
      db.Project.destroy({ where: { project_id } })
        .then(() => cb())
        .error(cb)
    return dbQueue.queue.push(job, callback)
  },

  _findExpiredProjectIds(callback) {
    if (callback == null) {
      callback = function (error, project_ids) {}
    }
    const job = function (cb) {
      const keepProjectsFrom = new Date(
        Date.now() - ProjectPersistenceManager.EXPIRY_TIMEOUT
      )
      const q = {}
      q[db.op.lt] = keepProjectsFrom
      return db.Project.findAll({ where: { lastAccessed: q } })
        .then((projects) =>
          cb(
            null,
            projects.map((project) => project.project_id)
          )
        )
        .error(cb)
    }

    return dbQueue.queue.push(job, callback)
  }
}

logger.log(
  { EXPIRY_TIMEOUT: ProjectPersistenceManager.EXPIRY_TIMEOUT },
  'project assets kept timeout'
)
<commit_msg>[misc] move import to avoid git conflict<commit_after>/* eslint-disable
    camelcase,
    handle-callback-err,
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
/*
 * decaffeinate suggestions:
 * DS101: Remove unnecessary use of Array.from
 * DS102: Remove unnecessary code created because of implicit returns
 * DS207: Consider shorter variations of null checks
 * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
 */
let ProjectPersistenceManager
const Metrics = require('./Metrics')
const UrlCache = require('./UrlCache')
const CompileManager = require('./CompileManager')
const db = require('./db')
const dbQueue = require('./DbQueue')
const async = require('async')
const logger = require('logger-sharelatex')
const oneDay = 24 * 60 * 60 * 1000
const Settings = require('settings-sharelatex')
const diskusage = require('diskusage')

module.exports = ProjectPersistenceManager = {
  EXPIRY_TIMEOUT: Settings.project_cache_length_ms || oneDay * 2.5,

  refreshExpiryTimeout(callback) {
    if (callback == null) {
      callback = function (error) {}
    }
    diskusage.check('/', function (err, stats) {
      if (err) {
        logger.err({ err: err }, 'error getting disk usage')
        return callback(err)
      }
      const lowDisk = stats.available / stats.total < 0.1
      const lowerExpiry = ProjectPersistenceManager.EXPIRY_TIMEOUT * 0.9
      if (lowDisk && Settings.project_cache_length_ms / 2 < lowerExpiry) {
        logger.warn(
          {
            stats: stats,
            newExpiryTimeoutInDays: (lowerExpiry / oneDay).toFixed(2)
          },
          'disk running low on space, modifying EXPIRY_TIMEOUT'
        )
        ProjectPersistenceManager.EXPIRY_TIMEOUT = lowerExpiry
      }
      callback()
    })
  },
  markProjectAsJustAccessed(project_id, callback) {
    if (callback == null) {
      callback = function (error) {}
    }
    const timer = new Metrics.Timer('db-bump-last-accessed')
    const job = (cb) =>
      db.Project.findOrCreate({ where: { project_id } })
        .spread((project, created) =>
          project
            .update({ lastAccessed: new Date() })
            .then(() => cb())
            .error(cb)
        )
        .error(cb)
    dbQueue.queue.push(job, (error) => {
      timer.done()
      callback(error)
    })
  },

  clearExpiredProjects(callback) {
    if (callback == null) {
      callback = function (error) {}
    }
    return ProjectPersistenceManager._findExpiredProjectIds(function (
      error,
      project_ids
    ) {
      if (error != null) {
        return callback(error)
      }
      logger.log({ project_ids }, 'clearing expired projects')
      const jobs = Array.from(project_ids || []).map((project_id) =>
        ((project_id) => (callback) =>
          ProjectPersistenceManager.clearProjectFromCache(project_id, function (
            err
          ) {
            if (err != null) {
              logger.error({ err, project_id }, 'error clearing project')
            }
            return callback()
          }))(project_id)
      )
      return async.series(jobs, function (error) {
        if (error != null) {
          return callback(error)
        }
        return CompileManager.clearExpiredProjects(
          ProjectPersistenceManager.EXPIRY_TIMEOUT,
          (error) => callback()
        )
      })
    })
  }, // ignore any errors from deleting directories

  clearProject(project_id, user_id, callback) {
    if (callback == null) {
      callback = function (error) {}
    }
    logger.log({ project_id, user_id }, 'clearing project for user')
    return CompileManager.clearProject(project_id, user_id, function (error) {
      if (error != null) {
        return callback(error)
      }
      return ProjectPersistenceManager.clearProjectFromCache(
        project_id,
        function (error) {
          if (error != null) {
            return callback(error)
          }
          return callback()
        }
      )
    })
  },

  clearProjectFromCache(project_id, callback) {
    if (callback == null) {
      callback = function (error) {}
    }
    logger.log({ project_id }, 'clearing project from cache')
    return UrlCache.clearProject(project_id, function (error) {
      if (error != null) {
        logger.err({ error, project_id }, 'error clearing project from cache')
        return callback(error)
      }
      return ProjectPersistenceManager._clearProjectFromDatabase(
        project_id,
        function (error) {
          if (error != null) {
            logger.err(
              { error, project_id },
              'error clearing project from database'
            )
          }
          return callback(error)
        }
      )
    })
  },

  _clearProjectFromDatabase(project_id, callback) {
    if (callback == null) {
      callback = function (error) {}
    }
    logger.log({ project_id }, 'clearing project from database')
    const job = (cb) =>
      db.Project.destroy({ where: { project_id } })
        .then(() => cb())
        .error(cb)
    return dbQueue.queue.push(job, callback)
  },

  _findExpiredProjectIds(callback) {
    if (callback == null) {
      callback = function (error, project_ids) {}
    }
    const job = function (cb) {
      const keepProjectsFrom = new Date(
        Date.now() - ProjectPersistenceManager.EXPIRY_TIMEOUT
      )
      const q = {}
      q[db.op.lt] = keepProjectsFrom
      return db.Project.findAll({ where: { lastAccessed: q } })
        .then((projects) =>
          cb(
            null,
            projects.map((project) => project.project_id)
          )
        )
        .error(cb)
    }

    return dbQueue.queue.push(job, callback)
  }
}

logger.log(
  { EXPIRY_TIMEOUT: ProjectPersistenceManager.EXPIRY_TIMEOUT },
  'project assets kept timeout'
)
<|endoftext|>


<commit_before>(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['backbone', 'react'], factory);
    } else {
        // Browser globals
        root.amdWeb = factory(root.Backbone, root.React);
    }
}(this, function (Backbone, React) {
    "use strict";

    var collection_behavior = {
      change_options: 'add remove reset sort',
      update_scheduler: function(func){ return _.debounce(func,0); }
    };
    var model_behavior = {
      change_options: 'change',
      update_scheduler: _.identity
      //note: if we debounce models too we can no longer use model attributes
      //as properties to react controlled components due to https://github.com/facebook/react/issues/955
    };

    var subscribe = function(component, model, customChangeOptions) {
        if (!model) {
            return;
        }

        var behavior = model instanceof Backbone.Collection ? collection_behavior : model_behavior;

        var triggerUpdate = behavior.update_scheduler(function() {
            if (component.isMounted())
                (component.onModelChange || component.forceUpdate).call(component);
        });

        model.on(customChangeOptions || behavior.change_options, triggerUpdate, component);
    };

    var unsubscribe = function(component, model) {
        if (!model) {
            return;
        }
        model.off(null, null, component);
    };
    React.BackboneMixin = function(prop_name, customChangeOptions){ return {
        componentDidMount: function() {
            // Whenever there may be a change in the Backbone data, trigger a reconcile.
            subscribe(this, this.props[prop_name], customChangeOptions);
        },
        componentWillReceiveProps: function(nextProps) {
            if (this.props[prop_name] === nextProps[prop_name]) {
                return;
            }

            unsubscribe(this, this.props[prop_name]);
            subscribe(this, nextProps[prop_name], customChangeOptions);

            if (typeof this.componentWillChangeModel === 'function') {
                this.componentWillChangeModel();
            }
        },
        componentDidUpdate: function(prevProps, prevState) {
            if (this.props[prop_name] === prevProps[prop_name]) {
                return;
            }

            if (typeof this.componentDidChangeModel === 'function') {
                this.componentDidChangeModel();
            }
        },
        componentWillUnmount: function() {
            // Ensure that we clean up any dangling references when the component is destroyed.
            unsubscribe(this, this.props[prop_name]);
        }
    };};

    React.BackboneViewMixin = {
        getModel: function() {
            return this.props.model;
        },
        model: function() {
            return this.getModel();
        },
        el: function() {
            return this.isMounted() && this.getDOMNode();
        }
    };

    React.createBackboneClass = function(spec) {
        var currentMixins = spec.mixins || [];

        spec.mixins = currentMixins.concat([
            React.BackboneMixin('model', spec.changeOptions),
            React.BackboneViewMixin
        ]);
        return React.createClass(spec);
    };

    return React;

}));
<commit_msg>Update react.backbone<commit_after>(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(['backbone', 'react'], factory);
  } else {
    // Browser globals
    root.amdWeb = factory(root.Backbone, root.React);
  }
}(this, function (Backbone, React) {
  "use strict";

  var collection_behavior = {
    changeOptions: 'add remove reset sort',
    update_scheduler: function(func) { return _.debounce(func, 0); }
  };
  var model_behavior = {
    changeOptions: 'change',
    update_scheduler: _.identity
    //note: if we debounce models too we can no longer use model attributes
    //as properties to react controlled components due to https://github.com/facebook/react/issues/955
  };

  var subscribe = function(component, model, customChangeOptions) {
    if (!model) {
      return;
    }

    var behavior = model instanceof Backbone.Collection ? collection_behavior : model_behavior;

    var triggerUpdate = behavior.update_scheduler(function() {
      if (component.isMounted())
        (component.onModelChange || component.forceUpdate).call(component);
    });
    var changeOptions = customChangeOptions || component.changeOptions || behavior.changeOptions;
    model.on(changeOptions, triggerUpdate, component);
  };

  var unsubscribe = function(component, model) {
    if (!model) {
      return;
    }
    model.off(null, null, component);
  };
  React.BackboneMixin = function(prop_name, customChangeOptions) { return {
    componentDidMount: function() {
      // Whenever there may be a change in the Backbone data, trigger a reconcile.
      subscribe(this, this.props[prop_name], customChangeOptions);
    },
    componentWillReceiveProps: function(nextProps) {
      if (this.props[prop_name] === nextProps[prop_name]) {
        return;
      }

      unsubscribe(this, this.props[prop_name]);
      subscribe(this, nextProps[prop_name], customChangeOptions);

      if (typeof this.componentWillChangeModel === 'function') {
        this.componentWillChangeModel();
      }
    },
    componentDidUpdate: function(prevProps, prevState) {
      if (this.props[prop_name] === prevProps[prop_name]) {
        return;
      }

      if (typeof this.componentDidChangeModel === 'function') {
        this.componentDidChangeModel();
      }
    },
    componentWillUnmount: function() {
      // Ensure that we clean up any dangling references when the component is destroyed.
      unsubscribe(this, this.props[prop_name]);
    }
  };};
  _.extend(React.BackboneMixin, React.BackboneMixin('model'));

  React.BackboneViewMixin = {
    getModel: function() {
      return this.props.model;
    },
    model: function() {
      return this.getModel();
    },
    el: function() {
      return this.isMounted() && this.getDOMNode();
    }
  };

  React.createBackboneClass = function(spec) {
    var currentMixins = spec.mixins || [];

    spec.mixins = currentMixins.concat([
      React.BackboneMixin('model'),
      React.BackboneViewMixin
    ]);
    return React.createClass(spec);
  };

  return React;

}));
<|endoftext|>


<commit_before>/**
 * Events.
 *
 * @mixin
 * @namespace Bolt.events
 *
 * @param {Object} bolt - The Bolt module.
 */
(function (bolt) {
    'use strict';

    /*
     * Bolt.events mixin container.
     *
     * @private
     * @type {Object}
     */
    var events = {};

    /*
     * Event broker object.
     *
     * @private
     * @type {Object}
     */
    var broker = $({});

    /**
     * Fires an event.
     *
     * @static
     * @function fire
     * @memberof Bolt.events
     *
     * @param {string} event       - Event type
     * @param {object} [parameter] - Additional parameters to pass along to the event handler
     */
    events.fire = function (event, parameter) {
        broker.trigger(event, parameter);
    };

    /**
     * Attach an event handler.
     *
     * @static
     * @function on
     * @memberof Bolt.events
     *
     * @param {string}   event   - Event type
     * @param {function} handler - Event handler
     */
    events.on = function (event, handler) {
        broker.on(event, handler);
    };

    // Apply mixin container
    bolt.events = events;

})(Bolt || {});
<commit_msg>Use triggerHandler() instead of trigger()<commit_after>/**
 * Events.
 *
 * @mixin
 * @namespace Bolt.events
 *
 * @param {Object} bolt - The Bolt module.
 */
(function (bolt) {
    'use strict';

    /*
     * Bolt.events mixin container.
     *
     * @private
     * @type {Object}
     */
    var events = {};

    /*
     * Event broker object.
     *
     * @private
     * @type {Object}
     */
    var broker = $({});

    /**
     * Fires an event.
     *
     * @static
     * @function fire
     * @memberof Bolt.events
     *
     * @param {string} event       - Event type
     * @param {object} [parameter] - Additional parameters to pass along to the event handler
     */
    events.fire = function (event, parameter) {
        broker.triggerHandler(event, parameter);
    };

    /**
     * Attach an event handler.
     *
     * @static
     * @function on
     * @memberof Bolt.events
     *
     * @param {string}   event   - Event type
     * @param {function} handler - Event handler
     */
    events.on = function (event, handler) {
        broker.on(event, handler);
    };

    // Apply mixin container
    bolt.events = events;

})(Bolt || {});
<|endoftext|>


<commit_before>var locastyle = locastyle || {};

locastyle.dropdown = (function() {
  'use strict';

  function init() {
    unbind();
    bindClickOnTriggers();
    bindClickOutsideTriggers();
  }

  function unbind() {
    $("[data-ls-module=dropdown] > a:first-child").off("click.ls");
    $("body").off("click.ls");
  }

  function bindClickOnTriggers() {
    $("[data-ls-module=dropdown] > a:first-child").on("click.ls", function(evt) {
      evt.preventDefault();
      var $target = $($(this).parents("[data-ls-module=dropdown]"));
      locastyle.dropdown.toggleDropdown($target);
      locastyle.dropdown.closeDropdown($target);
      setPositionVisible($target);
      evt.stopPropagation();
    });
  }

  function bindClickOutsideTriggers() {
    $("body").on("click.ls", function(){
      locastyle.dropdown.closeDropdown();
    });
  }

  function toggleDropdown($target) {
    if($target.find('a:eq(0)').hasClass('ls-disabled')){
      return false
    } else {
      $target.toggleClass("ls-active");
      locastyle.topbarCurtain.hideCurtains();
    }
  }

  function closeDropdown(el) {
    $("[data-ls-module=dropdown]").not(el).removeClass("ls-active");
  }

  function setPositionVisible($target){
    var $main = $('body');
    if($main.get(0).scrollWidth > $main.width()){
      $($target).addClass('ls-pos-right')
    }
  }

  return {
    init: init,
    unbind: unbind,
    toggleDropdown: toggleDropdown,
    closeDropdown: closeDropdown
  }

}());
<commit_msg>lint dropdown<commit_after>var locastyle = locastyle || {};

locastyle.dropdown = (function() {
  'use strict';

  function init() {
    unbind();
    bindClickOnTriggers();
    bindClickOutsideTriggers();
  }

  function unbind() {
    $("[data-ls-module=dropdown] > a:first-child").off("click.ls");
    $("body").off("click.ls");
  }

  function bindClickOnTriggers() {
    $("[data-ls-module=dropdown] > a:first-child").on("click.ls", function(evt) {
      evt.preventDefault();
      var $target = $($(this).parents("[data-ls-module=dropdown]"));
      locastyle.dropdown.toggleDropdown($target);
      locastyle.dropdown.closeDropdown($target);
      setPositionVisible($target);
      evt.stopPropagation();
    });
  }

  function bindClickOutsideTriggers() {
    $("body").on("click.ls", function(){
      locastyle.dropdown.closeDropdown();
    });
  }

  function toggleDropdown($target) {
    if($target.find('a:eq(0)').hasClass('ls-disabled')){
      return false;
    } else {
      $target.toggleClass("ls-active");
      locastyle.topbarCurtain.hideCurtains();
    }
  }

  function closeDropdown(el) {
    $("[data-ls-module=dropdown]").not(el).removeClass("ls-active");
  }

  function setPositionVisible($target){
    var $main = $('body');
    if($main.get(0).scrollWidth > $main.width()){
      $($target).addClass('ls-pos-right');
    }
  }

  return {
    init: init,
    unbind: unbind,
    toggleDropdown: toggleDropdown,
    closeDropdown: closeDropdown
  };

}());
<|endoftext|>