<commit_before>import React, { Component } from 'react'
import {
  View,
  StyleSheet,
  TouchableOpacity,
  Image,
  ScrollView,
  Alert
} from 'react-native'
import RightButtonNav from '../components/RightButtonNav'
import BookCollectItem from '../components/BookCollectTitle'
import HttpUtils from '../network/HttpUtils'
import { LISTS } from '../network/Urls'
import { INNERWIDTH, HEIGHT } from '../common/styles'
import { Actions } from 'react-native-router-flux'
import { SCENE_BOOK_COLLECT_ADD } from '../constants/scene'
import Toast from 'antd-mobile/lib/toast'
import Storage from '../common/storage'

const URL_SHOW = LISTS.show_list
const URL_ADD_BOOK = LISTS.collect_book
const URL_RM_LIST = LISTS.remove_list

export default class BookCollectPage extends Component {

  state = {
    lists: [],
    choosed: []
  }

  async componentDidMount() {
    const result = (await HttpUtils.post(URL_SHOW)) || {}
    const lists = result.data || []
    console.log(this)
    this.setState({ lists })
  }

  rightOnPress = async () => {
    if (this.props.title === '我的书单' || this.state.choosed.length == 0) {
      Actions.pop()
    }

    const tasks = []

    this.state.choosed.forEach((choosed) => {
      let {
        list_id
      } = this.state.lists.filter(list => list.list_name === choosed)[0]

      const params = {
        list_id,
        book_id: this.props.book.book_id,
        book_db_id: 1
      }

      console.log(URL_ADD_BOOK, params)

      tasks.push(HttpUtils.post(URL_ADD_BOOK, params))
    })

    await Promise.all(tasks)

    Toast.success('收藏成功！', 1)
    Actions.pop()
  }

  onPressButton(select, item) {
    let choosed = this.state.choosed
    if (select) {
      choosed = [...new Set([...choosed, item.list_name])]
    } else {
      choosed.splice(choosed.indexOf(item.list_name), 1)
    }
    this.setState({ choosed: choosed })
  }

  async onDelete(title) {
    let array = this.state.lists
    array.some(async (d, i) => {
      if (d.list_name === title) {
        array.splice(i, 1)
      }
      let params = {
        list_id: d.list_id
      }
      let result = (await HttpUtils.post(URL_RM_LIST, params)) || {}
      if (result.msg === '请求成功') {
        await this.setState({ lists: array })
        Toast.success('删除书单成功!', 1)
        await Storage.set('book_list', array)
        return true
      } else {
        Toast.offline(result.msg, 1)
      }
    })
  }

  onConfirm(title) {
    Alert.alert('确认删除', '您真的要删除这个书单吗?', [
      { text: '确认', onPress: this.onDelete.bind(this, title) },
      { text: '取消' }
    ])
  }

  render() {
    return (
      <View style={styles.container}>
        <RightButtonNav
          title={this.props.title}
          rightOnPress={() => this.rightOnPress()}
        />
        <TouchableOpacity
          style={styles.add}
          onPress={() => {
            let params = {
              onCallBack: async () => {
                let array = await Storage.get('book_list', [])
                this.setState({ lists: array })
              }
            }
            Actions[SCENE_BOOK_COLLECT_ADD](params)
          }}
        >
          <Image source={require('../../res/images/icon_add.png')} />
        </TouchableOpacity>
        <ScrollView style={styles.list}>
          {this.state.lists.map((item, i) => {
            return (
              <BookCollectItem
                item={item}
                big_title={this.props.title}
                onPress={(select, data) => this.onPressButton(select, data)}
                onDelete={title => {
                  this.onConfirm(title)
                }}
                key={item.list_id}
                data={item}
              />
            )
          })}
        </ScrollView>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: 'rgb(242,246,250)',
    height: HEIGHT
  },
  add: {
    width: INNERWIDTH,
    borderRadius: 8,
    marginLeft: 8,
    height: 48,
    marginTop: 8,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'white'
  },
  list: {
    marginTop: 20
  }
})
<commit_msg>feat(book collect): 收藏功能<commit_after>import React, { Component } from 'react'
import {
  View,
  StyleSheet,
  TouchableOpacity,
  Image,
  ScrollView,
  Alert
} from 'react-native'
import RightButtonNav from '../components/RightButtonNav'
import BookCollectItem from '../components/BookCollectTitle'
import HttpUtils from '../network/HttpUtils'
import { LISTS } from '../network/Urls'
import { INNERWIDTH, HEIGHT } from '../common/styles'
import { Actions } from 'react-native-router-flux'
import { SCENE_BOOK_COLLECT_ADD } from '../constants/scene'
import Toast from 'antd-mobile/lib/toast'
import Storage from '../common/storage'

const URL_SHOW = LISTS.show_list
const URL_ADD_BOOK = LISTS.collect_book
const URL_RM_LIST = LISTS.remove_list

export default class BookCollectPage extends Component {

  state = {
    lists: [],
    choosed: []
  }

  async componentDidMount() {
    const result = (await HttpUtils.post(URL_SHOW)) || {}
    const lists = result.data || []
    console.log(this)
    this.setState({ lists })
  }

  rightOnPress = async () => {
    if (this.props.title === '我的书单' || this.state.choosed.length == 0) {
      Actions.pop()
    }

    const tasks = []

    this.state.choosed.forEach((choosed) => {
      let {
        list_id
      } = this.state.lists.filter(list => list.list_name === choosed)[0]

      const params = {
        list_id,
        book_id: this.props.book.book_id,
        book_db_id: 1
      }

      tasks.push(HttpUtils.post(URL_ADD_BOOK, params))
    })

    const responses = await Promise.all(tasks)

    const successed = responses.every(res => res.status === 0)

    if (successed) {
      Toast.success('收藏成功！', 1)
      Actions.pop()
      return
    }

    Toast.success('收藏失败，请重试', 1)
  }

  onPressButton(select, item) {
    let choosed = this.state.choosed
    if (select) {
      choosed = [...new Set([...choosed, item.list_name])]
    } else {
      choosed.splice(choosed.indexOf(item.list_name), 1)
    }
    this.setState({ choosed: choosed })
  }

  async onDelete(title) {
    let array = this.state.lists
    array.some(async (d, i) => {
      if (d.list_name === title) {
        array.splice(i, 1)
      }
      let params = {
        list_id: d.list_id
      }
      let result = (await HttpUtils.post(URL_RM_LIST, params)) || {}
      if (result.msg === '请求成功') {
        await this.setState({ lists: array })
        Toast.success('删除书单成功!', 1)
        await Storage.set('book_list', array)
        return true
      } else {
        Toast.offline(result.msg, 1)
      }
    })
  }

  onConfirm(title) {
    Alert.alert('确认删除', '您真的要删除这个书单吗?', [
      { text: '确认', onPress: this.onDelete.bind(this, title) },
      { text: '取消' }
    ])
  }

  render() {
    return (
      <View style={styles.container}>
        <RightButtonNav
          title={this.props.title}
          rightOnPress={() => this.rightOnPress()}
        />
        <TouchableOpacity
          style={styles.add}
          onPress={() => {
            let params = {
              onCallBack: async () => {
                let array = await Storage.get('book_list', [])
                this.setState({ lists: array })
              }
            }
            Actions[SCENE_BOOK_COLLECT_ADD](params)
          }}
        >
          <Image source={require('../../res/images/icon_add.png')} />
        </TouchableOpacity>
        <ScrollView style={styles.list}>
          {this.state.lists.map((item, i) => {
            return (
              <BookCollectItem
                item={item}
                big_title={this.props.title}
                onPress={(select, data) => this.onPressButton(select, data)}
                onDelete={title => {
                  this.onConfirm(title)
                }}
                key={item.list_id}
                data={item}
              />
            )
          })}
        </ScrollView>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: 'rgb(242,246,250)',
    height: HEIGHT
  },
  add: {
    width: INNERWIDTH,
    borderRadius: 8,
    marginLeft: 8,
    height: 48,
    marginTop: 8,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'white'
  },
  list: {
    marginTop: 20
  }
})
<|endoftext|>


<commit_before>
var user = require('../Model/UserModel.js');
var Quiz = require('../Model/QuizModel.js');
var error = require('../Model/ErrorModel.js');

exports.createQuiz = function (req, res) {
    req.body.author=req.user._id;
    Quiz.createQuiz(req.body, function(err,quiz) {
        if (err) return res.status(500).json({
            code: 2,
            title: 'quiz-insertion-error',
            message: 'l\'inserimento del quiz è fallito'
        });
        else return res.send(quiz);
    });
}

exports.getQuiz = function (req, res, next) {
    Quiz.getQuiz(req.params.quizId, function(err, quiz) {
        if (err) return res.status(500).json({
            code: 323,
            title: 'Errore Questionario',
            message: 'Questionario non attivo'
        });
        else return res.send(quiz)
    })
}

exports.searchQuiz=function(req, res, next) {
    Quiz.searchQuiz(req.params.keyword, function(err, quiz){ console.log(req.params.keyword)
        if(err) return res.status(500).json({code:88, title: "Errore Quiz", message: "Nessuna quiz trovato"});
        else return res.send(quiz);
    })
};

exports.editQuiz = function (req, res, next) {
    /*quiz.editQuiz(req.body, function(err, quiz) {
        if (err) return res.status(500).json({
            code: 322,
            title: 'quiz-editing-error',
            message: 'byebye'
        });
        else return res.send(quiz);
    })*/
}

exports.getQuizSubscribe=function(req,res,next){
    console.log("entra");
    Quiz.getQuizSubscribe(req.user._id,function(err,quiz) {
        if (err) return res.status(500).json({
            code: 331,
            title: 'Iscrizione Utente Questionario Error',
            message: "Errore ottenimento lista questionari registrati"
        });
        else return res.send(quiz)
    })
}

exports.addUser = function (req, res, next) {
    Quiz.addUser(req.body.quizId, req.user._id, function (err, userId) {
        if (err) return res.status(500).json({
            code: 331,
            title: 'addUser-error',
            message: 'error occurred while adding user'
        });
        else return res.send({
            code: 331,
            title: "Iscrizione Utente Questionario OK",
            message: "L'utente si è registrato correttamente al questionario"
        })
    })
}

exports.removeUser = function (req, res, next) {
    Quiz.removeUser(req.body._id, function(err, userId) {
        if (err) return res.status(500).json({
            code: 331,
            title: 'removeUser-error',
            message: 'error occurred while removing user'
        });
        else return res.send(userId)
    })
}

exports.addActiveUser = function (req, res, next) {
    Quiz.addActiveUser(req.body._id, function(err, userId) {
        if (err) return res.status(500).json({
            code: 344,
            title: 'addActiveUser-error',
            message: 'error occurred while adding activeUser'
        });
        else return res.send(userId)
    })
}

exports.updateStatistic = function (req, res, next) {

}

exports.getPersonalQuizzes = function (req, res, next) {
    console.log(req.body);
    Quiz.getPersonalQuizzes(req.user._id, function(err, personalQuizzes) {
        if (err) return res.status(500).json({
            code: 2,
            title: 'visualizzazione-quiz-fallita',
            message: 'la visualizzazione dei quiz è fallita'
        });
        else {
            console.log(personalQuizzes);
            return res.send(personalQuizzes);
        }
    })

    /*quiz.getQuiz(req.body._id, function(err, quiz) {
     if (err) return res.status(500).json({
     code: 323,
     title: 'quiz-getting-error',
     message: 'byebyebye'
     });
     else return res.send(quiz)
     })*/
}

<commit_msg>Create quiz ok<commit_after>
var user = require('../Model/UserModel.js');
var Quiz = require('../Model/QuizModel.js');
var error = require('../Model/ErrorModel.js');

exports.createQuiz = function (req, res) {
    req.body.author=req.user._id;
    Quiz.createQuiz(req.body, function(err,quiz) {
        if (err) return res.status(500).json({
            code: 2,
            title: 'quiz-insertion-error',
            message: 'l\'inserimento del quiz è fallito'
        });
        else return res.send(quiz);
    });
}

exports.getQuiz = function (req, res, next) {
    Quiz.getQuiz(req.params.quizId, function(err, quiz) {
        if (err) return res.status(500).json({
            code: 323,
            title: 'Errore Questionario',
            message: err
        });
       else
            res.send(quiz)

    })
}

exports.searchQuiz=function(req, res, next) {
    Quiz.searchQuiz(req.params.keyword, function(err, quiz){ console.log(req.params.keyword)
        if(err) return res.status(500).json({code:88, title: "Errore Quiz", message: "Nessuna quiz trovato"});
        else return res.send(quiz);
    })
};

exports.editQuiz = function (req, res, next) {
    /*quiz.editQuiz(req.body, function(err, quiz) {
        if (err) return res.status(500).json({
            code: 322,
            title: 'quiz-editing-error',
            message: 'byebye'
        });
        else return res.send(quiz);
    })*/
}

exports.getQuizSubscribe=function(req,res,next){
    Quiz.getQuizSubscribe(req.user._id,function(err,quiz) {
        console.log(quiz)
        if (err) return res.status(500).json({
            code: 331,
            title: 'Iscrizione Utente Questionario Error',
            message: "Errore ottenimento lista questionari registrati"
        });
        else return res.send(quiz)
    })
}

exports.addUser = function (req, res, next) {
    Quiz.addUser(req.body.quizId, req.user._id, function (err, userId) {
        if (err) return res.status(500).json({
            code: 331,
            title: 'addUser-error',
            message: 'error occurred while adding user'
        });
        else return res.send({
            code: 331,
            title: "Iscrizione Utente Questionario OK",
            message: "L'utente si è registrato correttamente al questionario"
        })
    })
}

exports.removeUser = function (req, res, next) {
    Quiz.removeUser(req.body._id, function(err, userId) {
        if (err) return res.status(500).json({
            code: 331,
            title: 'removeUser-error',
            message: 'error occurred while removing user'
        });
        else return res.send(userId)
    })
}

exports.addActiveUser = function (req, res, next) {
    Quiz.addActiveUser(req.body._id, function(err, userId) {
        if (err) return res.status(500).json({
            code: 344,
            title: 'addActiveUser-error',
            message: 'error occurred while adding activeUser'
        });
        else return res.send(userId)
    })
}

exports.updateStatistic = function (req, res, next) {

}

exports.getPersonalQuizzes = function (req, res, next) {
    console.log(req.body);
    Quiz.getPersonalQuizzes(req.user._id, function(err, personalQuizzes) {
        if (err) return res.status(500).json({
            code: 2,
            title: 'visualizzazione-quiz-fallita',
            message: 'la visualizzazione dei quiz è fallita'
        });
        else {
            console.log(personalQuizzes);
            return res.send(personalQuizzes);
        }
    })

    /*quiz.getQuiz(req.body._id, function(err, quiz) {
     if (err) return res.status(500).json({
     code: 323,
     title: 'quiz-getting-error',
     message: 'byebyebye'
     });
     else return res.send(quiz)
     })*/
}

<|endoftext|>


<commit_before>/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";
// Components.utils.import("resource://gre/modules/NetUtil.jsm");
//let wantLogging = true;
/**
 * An adapter that handles data transfers between the debugger client and
 * server. It can work with both nsIPipe and nsIServerSocket transports so
 * long as the properly created input and output streams are specified.
 * (However, for intra-process connections, LocalDebuggerTransport, below,
 * is more efficient than using an nsIPipe pair with DebuggerTransport.)
 *
 * @param aInput nsIInputStream
 *        The input stream.
 * @param aOutput nsIAsyncOutputStream
 *        The output stream.
 *
 * Given a DebuggerTransport instance dt:
 * 1) Set dt.hooks to a packet handler object (described below).
 * 2) Call dt.ready() to begin watching for input packets.
 * 3) Call dt.send() to send packets as you please, and handle incoming
 *    packets passed to hook.onPacket.
 * 4) Call dt.close() to close the connection, and disengage from the event
 *    loop.
 *
 * A packet handler is an object with two methods:
 *
 * - onPacket(packet) - called when we have received a complete packet.
 *   |Packet| is the parsed form of the packet --- a JavaScript value, not
 *   a JSON-syntax string.
 *
 * - onClosed(status) - called when the connection is closed. |Status| is
 *   an nsresult, of the sort passed to nsIRequestObserver.
 *
 * Data is transferred as a JSON packet serialized into a string, with the
 * string length prepended to the packet, followed by a colon
 * ([length]:[packet]). The contents of the JSON packet are specified in
 * the Remote Debugging Protocol specification.
 */
this.DebuggerTransport = function DebuggerTransport(aInput, aOutput)
{
  this._input = aInput;
  this._output = aOutput;

  this._converter = null;//Cc["@mozilla.org/intl/scriptableunicodeconverter"]
    // .createInstance(Ci.nsIScriptableUnicodeConverter);
  // this._converter.charset = "UTF-8";

  this._outgoing = "";
  this._incoming = "";

  this.hooks = null;
}

DebuggerTransport.prototype = {
  /**
   * Transmit a packet.
   *
   * This method returns immediately, without waiting for the entire
   * packet to be transmitted, registering event handlers as needed to
   * transmit the entire packet. Packets are transmitted in the order
   * they are passed to this method.
   */
  send: function DT_send(aPacket) {
    let data = JSON.stringify(aPacket);
    // data = this._converter.ConvertFromUnicode(data);

    let data_for_len = utf16to8(data);

    this._outgoing = data_for_len.length + ':' + data;

    this._flushOutgoing();
  },

  /**
   * Close the transport.
   */
  close: function DT_close() {
    this._input.close();
    this._output.close();
  },

  /**
   * Flush the outgoing stream.
   */
  _flushOutgoing: function DT_flushOutgoing() {
    if (this._outgoing.length > 0) {
      // var threadManager = Cc["@mozilla.org/thread-manager;1"].getService();
      // this._output.asyncWait(this, 0, 0, threadManager.currentThread);
      if (wantLogging) {
        log("outgoing: " + this._outgoing);//.substring(0, 200));
      };
      _bufferWrite(this._outgoing);
    }
  },

  onOutputStreamReady:
  makeInfallible(function DT_onOutputStreamReady(aStream) {
    let written = 0;
    try {
      written = aStream.write(this._outgoing, this._outgoing.length);
    } catch(e if e.result == Components.results.NS_BASE_STREAM_CLOSED) {
      dumpn("Connection closed.");
      this.close();
      return;
    }
    this._outgoing = this._outgoing.slice(written);
    this._flushOutgoing();
  }, "DebuggerTransport.prototype.onOutputStreamReady"),

  /**
   * Initialize the input stream for reading. Once this method has been
   * called, we watch for packets on the input stream, and pass them to
   * this.hook.onPacket.
   */
  ready: function DT_ready() {
    // let pump = Cc["@mozilla.org/network/input-stream-pump;1"]
    //   .createInstance(Ci.nsIInputStreamPump);
    // pump.init(this._input, -1, -1, 0, 0, false);
    // pump.asyncRead(this, null);
  },

  // nsIStreamListener
  onStartRequest:
  makeInfallible(function DT_onStartRequest(aRequest, aContext) {},
                 "DebuggerTransport.prototype.onStartRequest"),

  onStopRequest:
  makeInfallible(function DT_onStopRequest(aRequest, aContext, aStatus) {
    this.close();
    if (this.hooks) {
      this.hooks.onClosed(aStatus);
      this.hooks = null;
    }
  }, "DebuggerTransport.prototype.onStopRequest"),

  onDataAvailable: makeInfallible(function DT_onDataAvailable (incoming)
//  makeInfallible(function DT_onDataAvailable(aRequest, aContext,
//                                             aStream, aOffset, aCount)
  {
    this._incoming = incoming;//+= NetUtil.readInputStreamToString(aStream,
                               //                       aStream.available());
    while (this._processIncoming()) {};
  }, "DebuggerTransport.prototype.onDataAvailable"),

  /**
   * Process incoming packets. Returns true if a packet has been received, either
   * if it was properly parsed or not. Returns false if the incoming stream does
   * not contain a full packet yet. After a proper packet is parsed, the dispatch
   * handler DebuggerTransport.hooks.onPacket is called with the packet as a
   * parameter.
   */
  _processIncoming: function DT__processIncoming() {
    // Well this is ugly.
    let sep = this._incoming.indexOf(':');
    if (sep < 0) {
      // Incoming packet length is too big anyway - drop the connection.
      if (this._incoming.length > 20) {
        this.close();
      }
      return false;
    }

    let count = this._incoming.substring(0, sep);
    // Check for a positive number with no garbage afterwards.
    if (!/^[0-9]+$/.exec(count)) {
      this.close();
      return false;
    }

    count = +count;
    if (this._incoming.length - (sep + 1) < count) {
      // Don't have a complete request yet.
      return false;
    }

    // We have a complete request, pluck it out of the data and parse it.
    this._incoming = this._incoming.substring(sep + 1);
    let packet = this._incoming.substring(0, count);
    this._incoming = this._incoming.substring(count);

    try {
      // packet = this._converter.ConvertToUnicode(packet);
      packet = utf8to16(packet);
      var parsed = JSON.parse(packet);
    } catch(e) {
      let msg = "Error parsing incoming packet: " + packet + " (" + e + " - " + e.stack + ")";
      // if (Cu.reportError) {
      //   Cu.reportError(msg);
      // }
      dump(msg + "\n");
      return true;
    }

    if (wantLogging) {
      dumpn("Got: " + JSON.stringify(parsed, null, 2));
    }

    let self = this;

    // Services.tm.currentThread.dispatch(makeInfallible(function() {
    // Ensure the hooks are still around by the time this runs (they will go
    // away when the transport is closed).
      if (self.hooks) {
        self.hooks.onPacket(parsed);
      }
    // }, "DebuggerTransport instance's this.hooks.onPacket"), 0);

    return true;
  }
}

/**
 * An adapter that handles data transfers between the debugger client and
 * server when they both run in the same process. It presents the same API as
 * DebuggerTransport, but instead of transmitting serialized messages across a
 * connection it merely calls the packet dispatcher of the other side.
 *
 * @param aOther LocalDebuggerTransport
 *        The other endpoint for this debugger connection.
 *
 * @see DebuggerTransport
 */
this.LocalDebuggerTransport = function LocalDebuggerTransport(aOther)
{
  this.other = aOther;
  this.hooks = null;

  /*
   * A packet number, shared between this and this.other. This isn't used
   * by the protocol at all, but it makes the packet traces a lot easier to
   * follow.
   */
  this._serial = this.other ? this.other._serial : { count: 0 };
}

LocalDebuggerTransport.prototype = {
  /**
   * Transmit a message by directly calling the onPacket handler of the other
   * endpoint.
   */
  send: function LDT_send(aPacket) {
    let serial = this._serial.count++;
    if (wantLogging) {
      /* Check 'from' first, as 'echo' packets have both. */
      if (aPacket.from) {
        dumpn("Packet " + serial + " sent from " + uneval(aPacket.from));
      } else if (aPacket.to) {
        dumpn("Packet " + serial + " sent to " + uneval(aPacket.to));
      }
    }
    this._deepFreeze(aPacket);
    let other = this.other;
    if (other) {
      Services.tm.currentThread.dispatch(makeInfallible(function() {
        // Avoid the cost of JSON.stringify() when logging is disabled.
        if (wantLogging) {
          dumpn("Received packet " + serial + ": " + JSON.stringify(aPacket, null, 2));
        }
        if (other.hooks) {
          other.hooks.onPacket(aPacket);
        }
      }, "LocalDebuggerTransport instance's this.other.hooks.onPacket"), 0);
    }
  },

  /**
   * Close the transport.
   */
  close: function LDT_close() {
    if (this.other) {
      // Remove the reference to the other endpoint before calling close(), to
      // avoid infinite recursion.
      let other = this.other;
      this.other = null;
      other.close();
    }
    if (this.hooks) {
      try {
        this.hooks.onClosed();
      } catch(ex) {
        Components.utils.reportError(ex);
      }
      this.hooks = null;
    }
  },

  /**
   * An empty method for emulating the DebuggerTransport API.
   */
  ready: function LDT_ready() {},

  /**
   * Helper function that makes an object fully immutable.
   */
  _deepFreeze: function LDT_deepFreeze(aObject) {
    Object.freeze(aObject);
    for (let prop in aObject) {
      // Freeze the properties that are objects, not on the prototype, and not
      // already frozen. Note that this might leave an unfrozen reference
      // somewhere in the object if there is an already frozen object containing
      // an unfrozen object.
      if (aObject.hasOwnProperty(prop) && typeof aObject === "object" &&
          !Object.isFrozen(aObject)) {
        this._deepFreeze(o[prop]);
      }
    }
  }
};

/**
 * A transport for the debugging protocol that uses nsIMessageSenders to
 * exchange packets with servers running in child processes.
 *
 * In the parent process, |aSender| should be the nsIMessageSender for the
 * child process. In a child process, |aSender| should be the child process
 * message manager, which sends packets to the parent.
 *
 * aPrefix is a string included in the message names, to distinguish
 * multiple servers running in the same child process.
 *
 * This transport exchanges messages named 'debug:<prefix>:packet', where
 * <prefix> is |aPrefix|, whose data is the protocol packet.
 */
function ChildDebuggerTransport(aSender, aPrefix) {
  this._sender = aSender.QueryInterface(Components.interfaces.nsIMessageSender);
  this._messageName = "debug:" + aPrefix + ":packet";
}

/*
 * To avoid confusion, we use 'message' to mean something that
 * nsIMessageSender conveys, and 'packet' to mean a remote debugging
 * protocol packet.
 */
ChildDebuggerTransport.prototype = {
  constructor: ChildDebuggerTransport,

  hooks: null,

  ready: function () {
    this._sender.addMessageListener(this._messageName, this);
  },

  close: function () {
    this._sender.removeMessageListener(this._messageName, this);
    this.hooks.onClosed();
  },

  receiveMessage: function ({data}) {
    this.hooks.onPacket(data);
  },

  send: function (packet) {
    this._sender.sendAsyncMessage(this._messageName, packet);
  }
};
<commit_msg>fix encode error on win32<commit_after>/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";
// Components.utils.import("resource://gre/modules/NetUtil.jsm");
//let wantLogging = true;
/**
 * An adapter that handles data transfers between the debugger client and
 * server. It can work with both nsIPipe and nsIServerSocket transports so
 * long as the properly created input and output streams are specified.
 * (However, for intra-process connections, LocalDebuggerTransport, below,
 * is more efficient than using an nsIPipe pair with DebuggerTransport.)
 *
 * @param aInput nsIInputStream
 *        The input stream.
 * @param aOutput nsIAsyncOutputStream
 *        The output stream.
 *
 * Given a DebuggerTransport instance dt:
 * 1) Set dt.hooks to a packet handler object (described below).
 * 2) Call dt.ready() to begin watching for input packets.
 * 3) Call dt.send() to send packets as you please, and handle incoming
 *    packets passed to hook.onPacket.
 * 4) Call dt.close() to close the connection, and disengage from the event
 *    loop.
 *
 * A packet handler is an object with two methods:
 *
 * - onPacket(packet) - called when we have received a complete packet.
 *   |Packet| is the parsed form of the packet --- a JavaScript value, not
 *   a JSON-syntax string.
 *
 * - onClosed(status) - called when the connection is closed. |Status| is
 *   an nsresult, of the sort passed to nsIRequestObserver.
 *
 * Data is transferred as a JSON packet serialized into a string, with the
 * string length prepended to the packet, followed by a colon
 * ([length]:[packet]). The contents of the JSON packet are specified in
 * the Remote Debugging Protocol specification.
 */
this.DebuggerTransport = function DebuggerTransport(aInput, aOutput)
{
  this._input = aInput;
  this._output = aOutput;

  this._converter = null;//Cc["@mozilla.org/intl/scriptableunicodeconverter"]
    // .createInstance(Ci.nsIScriptableUnicodeConverter);
  // this._converter.charset = "UTF-8";

  this._outgoing = "";
  this._incoming = "";

  this.hooks = null;
}

DebuggerTransport.prototype = {
  /**
   * Transmit a packet.
   *
   * This method returns immediately, without waiting for the entire
   * packet to be transmitted, registering event handlers as needed to
   * transmit the entire packet. Packets are transmitted in the order
   * they are passed to this method.
   */
  send: function DT_send(aPacket) {
    let data = JSON.stringify(aPacket);
    // data = this._converter.ConvertFromUnicode(data);

    let data_for_len = utf16to8(data);

    this._outgoing = data_for_len.length + ':' + data_for_len;

    this._flushOutgoing();
  },

  /**
   * Close the transport.
   */
  close: function DT_close() {
    this._input.close();
    this._output.close();
  },

  /**
   * Flush the outgoing stream.
   */
  _flushOutgoing: function DT_flushOutgoing() {
    if (this._outgoing.length > 0) {
      // var threadManager = Cc["@mozilla.org/thread-manager;1"].getService();
      // this._output.asyncWait(this, 0, 0, threadManager.currentThread);
      if (wantLogging) {
        log("outgoing: " + this._outgoing);//.substring(0, 200));
      };
      _bufferWrite(this._outgoing);
    }
  },

  onOutputStreamReady:
  makeInfallible(function DT_onOutputStreamReady(aStream) {
    let written = 0;
    try {
      written = aStream.write(this._outgoing, this._outgoing.length);
    } catch(e if e.result == Components.results.NS_BASE_STREAM_CLOSED) {
      dumpn("Connection closed.");
      this.close();
      return;
    }
    this._outgoing = this._outgoing.slice(written);
    this._flushOutgoing();
  }, "DebuggerTransport.prototype.onOutputStreamReady"),

  /**
   * Initialize the input stream for reading. Once this method has been
   * called, we watch for packets on the input stream, and pass them to
   * this.hook.onPacket.
   */
  ready: function DT_ready() {
    // let pump = Cc["@mozilla.org/network/input-stream-pump;1"]
    //   .createInstance(Ci.nsIInputStreamPump);
    // pump.init(this._input, -1, -1, 0, 0, false);
    // pump.asyncRead(this, null);
  },

  // nsIStreamListener
  onStartRequest:
  makeInfallible(function DT_onStartRequest(aRequest, aContext) {},
                 "DebuggerTransport.prototype.onStartRequest"),

  onStopRequest:
  makeInfallible(function DT_onStopRequest(aRequest, aContext, aStatus) {
    this.close();
    if (this.hooks) {
      this.hooks.onClosed(aStatus);
      this.hooks = null;
    }
  }, "DebuggerTransport.prototype.onStopRequest"),

  onDataAvailable: makeInfallible(function DT_onDataAvailable (incoming)
//  makeInfallible(function DT_onDataAvailable(aRequest, aContext,
//                                             aStream, aOffset, aCount)
  {
    this._incoming = incoming;//+= NetUtil.readInputStreamToString(aStream,
                               //                       aStream.available());
    while (this._processIncoming()) {};
  }, "DebuggerTransport.prototype.onDataAvailable"),

  /**
   * Process incoming packets. Returns true if a packet has been received, either
   * if it was properly parsed or not. Returns false if the incoming stream does
   * not contain a full packet yet. After a proper packet is parsed, the dispatch
   * handler DebuggerTransport.hooks.onPacket is called with the packet as a
   * parameter.
   */
  _processIncoming: function DT__processIncoming() {
    // Well this is ugly.
    let sep = this._incoming.indexOf(':');
    if (sep < 0) {
      // Incoming packet length is too big anyway - drop the connection.
      if (this._incoming.length > 20) {
        this.close();
      }
      return false;
    }

    let count = this._incoming.substring(0, sep);
    // Check for a positive number with no garbage afterwards.
    if (!/^[0-9]+$/.exec(count)) {
      this.close();
      return false;
    }

    count = +count;
    if (this._incoming.length - (sep + 1) < count) {
      // Don't have a complete request yet.
      return false;
    }

    // We have a complete request, pluck it out of the data and parse it.
    this._incoming = this._incoming.substring(sep + 1);
    let packet = this._incoming.substring(0, count);
    this._incoming = this._incoming.substring(count);

    try {
      // packet = this._converter.ConvertToUnicode(packet);
      packet = utf8to16(packet);
      var parsed = JSON.parse(packet);
    } catch(e) {
      let msg = "Error parsing incoming packet: " + packet + " (" + e + " - " + e.stack + ")";
      // if (Cu.reportError) {
      //   Cu.reportError(msg);
      // }
      dump(msg + "\n");
      return true;
    }

    if (wantLogging) {
      dumpn("Got: " + JSON.stringify(parsed, null, 2));
    }

    let self = this;

    // Services.tm.currentThread.dispatch(makeInfallible(function() {
    // Ensure the hooks are still around by the time this runs (they will go
    // away when the transport is closed).
      if (self.hooks) {
        self.hooks.onPacket(parsed);
      }
    // }, "DebuggerTransport instance's this.hooks.onPacket"), 0);

    return true;
  }
}

/**
 * An adapter that handles data transfers between the debugger client and
 * server when they both run in the same process. It presents the same API as
 * DebuggerTransport, but instead of transmitting serialized messages across a
 * connection it merely calls the packet dispatcher of the other side.
 *
 * @param aOther LocalDebuggerTransport
 *        The other endpoint for this debugger connection.
 *
 * @see DebuggerTransport
 */
this.LocalDebuggerTransport = function LocalDebuggerTransport(aOther)
{
  this.other = aOther;
  this.hooks = null;

  /*
   * A packet number, shared between this and this.other. This isn't used
   * by the protocol at all, but it makes the packet traces a lot easier to
   * follow.
   */
  this._serial = this.other ? this.other._serial : { count: 0 };
}

LocalDebuggerTransport.prototype = {
  /**
   * Transmit a message by directly calling the onPacket handler of the other
   * endpoint.
   */
  send: function LDT_send(aPacket) {
    let serial = this._serial.count++;
    if (wantLogging) {
      /* Check 'from' first, as 'echo' packets have both. */
      if (aPacket.from) {
        dumpn("Packet " + serial + " sent from " + uneval(aPacket.from));
      } else if (aPacket.to) {
        dumpn("Packet " + serial + " sent to " + uneval(aPacket.to));
      }
    }
    this._deepFreeze(aPacket);
    let other = this.other;
    if (other) {
      Services.tm.currentThread.dispatch(makeInfallible(function() {
        // Avoid the cost of JSON.stringify() when logging is disabled.
        if (wantLogging) {
          dumpn("Received packet " + serial + ": " + JSON.stringify(aPacket, null, 2));
        }
        if (other.hooks) {
          other.hooks.onPacket(aPacket);
        }
      }, "LocalDebuggerTransport instance's this.other.hooks.onPacket"), 0);
    }
  },

  /**
   * Close the transport.
   */
  close: function LDT_close() {
    if (this.other) {
      // Remove the reference to the other endpoint before calling close(), to
      // avoid infinite recursion.
      let other = this.other;
      this.other = null;
      other.close();
    }
    if (this.hooks) {
      try {
        this.hooks.onClosed();
      } catch(ex) {
        Components.utils.reportError(ex);
      }
      this.hooks = null;
    }
  },

  /**
   * An empty method for emulating the DebuggerTransport API.
   */
  ready: function LDT_ready() {},

  /**
   * Helper function that makes an object fully immutable.
   */
  _deepFreeze: function LDT_deepFreeze(aObject) {
    Object.freeze(aObject);
    for (let prop in aObject) {
      // Freeze the properties that are objects, not on the prototype, and not
      // already frozen. Note that this might leave an unfrozen reference
      // somewhere in the object if there is an already frozen object containing
      // an unfrozen object.
      if (aObject.hasOwnProperty(prop) && typeof aObject === "object" &&
          !Object.isFrozen(aObject)) {
        this._deepFreeze(o[prop]);
      }
    }
  }
};

/**
 * A transport for the debugging protocol that uses nsIMessageSenders to
 * exchange packets with servers running in child processes.
 *
 * In the parent process, |aSender| should be the nsIMessageSender for the
 * child process. In a child process, |aSender| should be the child process
 * message manager, which sends packets to the parent.
 *
 * aPrefix is a string included in the message names, to distinguish
 * multiple servers running in the same child process.
 *
 * This transport exchanges messages named 'debug:<prefix>:packet', where
 * <prefix> is |aPrefix|, whose data is the protocol packet.
 */
function ChildDebuggerTransport(aSender, aPrefix) {
  this._sender = aSender.QueryInterface(Components.interfaces.nsIMessageSender);
  this._messageName = "debug:" + aPrefix + ":packet";
}

/*
 * To avoid confusion, we use 'message' to mean something that
 * nsIMessageSender conveys, and 'packet' to mean a remote debugging
 * protocol packet.
 */
ChildDebuggerTransport.prototype = {
  constructor: ChildDebuggerTransport,

  hooks: null,

  ready: function () {
    this._sender.addMessageListener(this._messageName, this);
  },

  close: function () {
    this._sender.removeMessageListener(this._messageName, this);
    this.hooks.onClosed();
  },

  receiveMessage: function ({data}) {
    this.hooks.onPacket(data);
  },

  send: function (packet) {
    this._sender.sendAsyncMessage(this._messageName, packet);
  }
};
<|endoftext|>


<commit_before>/**
* This looks at static needs parameter in components and waits for the promise to be fullfilled
* It is used to make sure server side rendered pages wait for APIs to resolve before returning res.end()
* As seen in: https://github.com/caljrimmer/isomorphic-redux-app
*/

export function fetchComponentDataBeforeRender(dispatch, components, params) {
  const needs = components.reduce((prev, current) => {
    return (current.need || [])
      .concat((current.WrappedComponent ? current.WrappedComponent.need : []) || [])
      .concat(prev);
    }, []);
    const promises = needs.map(need => dispatch(need(params)));
    return Promise.all(promises);
}
<commit_msg>fix duplicate fetch in WrappedComponent.need<commit_after>/**
* This looks at static needs parameter in components and waits for the promise to be fullfilled
* It is used to make sure server side rendered pages wait for APIs to resolve before returning res.end()
* As seen in: https://github.com/caljrimmer/isomorphic-redux-app
*/

export function fetchComponentDataBeforeRender(dispatch, components, params) {
  const needs = components.reduce((prev, current) => {
    return (current.need || [])
      .concat(prev);
    }, []);
    const promises = needs.map(need => dispatch(need(params)));
    return Promise.all(promises);
}
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';

// Import Style
import styles from './App.css';

// Import Components
import Helmet from 'react-helmet';
import DevTools from './components/DevTools';
import Header from './components/Header/Header';
import Footer from './components/Footer/Footer';

// Import Actions

export class App extends Component {
  constructor(props) {
    super(props);
    this.state = { isMounted: false };
  }

  componentDidMount() {
    this.setState({isMounted: true}); // eslint-disable-line
  }

  render() {
    return (

        {this.state.isMounted && !window.devToolsExtension && process.env.NODE_ENV === 'development' && <DevTools />}

          <Helmet
            title="Social Pulse"
            titleTemplate="%s - Blog App"
            meta={[
              { charset: 'utf-8' },
              {
                'http-equiv': 'X-UA-Compatible',
                content: 'IE=edge',
              },
              {
                name: 'viewport',
                content: 'width=device-width, initial-scale=1',
              },
            ]}
          />

            {this.props.children}

    );
  }
}

App.propTypes = {
  children: PropTypes.object.isRequired,
  dispatch: PropTypes.func.isRequired,
};

// Retrieve data from store as props
function mapStateToProps(store) {
  return {
    intl: store.intl,
  };
}

export default connect(mapStateToProps)(App);
<commit_msg>Remove DevTool popup<commit_after>import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';

// Import Style
import styles from './App.css';

// Import Components
import Helmet from 'react-helmet';
// import DevTools from './components/DevTools';
import Header from './components/Header/Header';
import Footer from './components/Footer/Footer';

// Import Actions

export class App extends Component {
  constructor(props) {
    super(props);
    this.state = { isMounted: false };
  }

  componentDidMount() {
    this.setState({isMounted: true}); // eslint-disable-line
  }

  render() {
    return (

        {/* this.state.isMounted && !window.devToolsExtension && process.env.NODE_ENV === 'development' && <DevTools /> */}

          <Helmet
            title="Social Pulse"
            titleTemplate="%s - Blog App"
            meta={[
              { charset: 'utf-8' },
              {
                'http-equiv': 'X-UA-Compatible',
                content: 'IE=edge',
              },
              {
                name: 'viewport',
                content: 'width=device-width, initial-scale=1',
              },
            ]}
          />

            {this.props.children}

    );
  }
}

App.propTypes = {
  children: PropTypes.object.isRequired,
  dispatch: PropTypes.func.isRequired,
};

// Retrieve data from store as props
function mapStateToProps(store) {
  return {
    intl: store.intl,
  };
}

export default connect(mapStateToProps)(App);
<|endoftext|>


<commit_before>'use strict';

/*jshint expr:true */

/**
 * Module dependencies.
 */
var assert = require('assert'),
        users = require('./models/user.server.model'),
	events = require('./models/event.server.model');

/**
* Global Variabls used for testing
*/
var event1, event2, event1d, ptor;

/**
*  Tests
*/

describe('Admin Page Protractor End-To-End Tests',function() {

	ptor = protractor.getInstance();

	it('should be able to visit the sign in page',function() {
		browser.get('http://localhost:3000/');
		browser.waitForAngular();
		expect(ptor.getCurrentUrl()).toContain('signin');
	});

	it('should be able to sign in',function() {
		browser.waitForAngular();
		expect(browser.getTitle()).toEqual('frank Recruiter System - Development Environment');
        	element(by.model('credentials.email')).sendKeys('demo@example.com');
        	element(by.model('credentials.password')).sendKeys('password');

        	element(by.css('button[type="submit"]')).click(); //Can select obscure entities
	});

	it('should be able to sign out',function() {
		element(by.css('.dropdown-menu a[href="/auth/signout"]'));
		browser.waitForAngular();
		expect(ptor.getCurrentUrl()).toContain('signin');
	});

	it('should be able to visit the sign in page',function() {
		browser.get('http://localhost:3000/');
		browser.waitForAngular();
		expect(ptor.getCurrentUrl()).toContain('signin');
	});

	it('should be able to sign in',function() {
		element(by.model('credentials.email')).sendKeys('demo@example.com');
        	element(by.model('credentials.password')).sendKeys('password');
        	element(by.css('button[type="submit"]')).click();
        	browser.waitForAngular();
	});
});

<commit_msg>Using clicks to sign out instead of get<commit_after>'use strict';

/*jshint expr:true */

/**
 * Module dependencies.
 */
var assert = require('assert'),
        users = require('./models/user.server.model'),
	events = require('./models/event.server.model');

/**
* Global Variabls used for testing
*/
var event1, event2, event1d, ptor;

/**
*  Tests
*/

describe('Admin Page Protractor End-To-End Tests',function() {

	ptor = protractor.getInstance();

	it('should be able to visit the sign in page',function() {
		browser.get('http://localhost:3000/');
		browser.waitForAngular();
		expect(ptor.getCurrentUrl()).toContain('signin');
	});

	it('should be able to sign in',function() {
		browser.waitForAngular();
		expect(browser.getTitle()).toEqual('frank Recruiter System - Development Environment');
        	element(by.model('credentials.email')).sendKeys('demo@example.com');
        	element(by.model('credentials.password')).sendKeys('password');

        	element(by.css('button[type="submit"]')).click();
	});

	it('should be able to sign out',function() {
		element(by.css('.dropdown-toggle span[data-ng-bind="authentication.user.fName"]')).click();
		browser.waitForAngular();
		element(by.css('.dropdown-menu a[href="/auth/signout"]')).click();
		browser.waitForAngular();
		expect(ptor.getCurrentUrl()).toContain('signin');
	});

	it('should be able to visit the sign in page',function() {
		browser.get('http://localhost:3000/');
		browser.waitForAngular();
		expect(ptor.getCurrentUrl()).toContain('signin');
	});

	it('should be able to sign in',function() {
		element(by.model('credentials.email')).sendKeys('demo@example.com');
        	element(by.model('credentials.password')).sendKeys('password');
        	element(by.css('button[type="submit"]')).click();
        	browser.waitForAngular();
	});
});

<|endoftext|>


<commit_before>'use strict';

const fse = require('fs-extra');
const uglify = require('uglify-es');

const processor = require('./processor');

module.exports = {
    /**
     * Load, minifies, and then injects the contents of
     * `js/editor-libs/perf.js` into the head of the document
     * @param {string} tmpl - The template as a string
     * @return {string} The template as a string with the perf script injected
     */
    injectPerf(tmpl) {
        const regex = /%inject-perf%/g;
        const perfJs = './js/editor-libs/perf.js';
        let minified = uglify.minify(fse.readFileSync(perfJs, 'utf-8')).code;
        return tmpl.replace(regex, minified);
    },
    /**
     * Sets the appropriate class on the tabbed editor’s container
     * element based on the height property defined in the example’s
     * meta data
     * @param {Object} currentPage - The current page object
     * @param {String} tmpl - The template as a string
     *
     * @returns The processed template with the height class set
     */
    setEditorHeight: function(currentPage, tmpl) {
        const regex = /%editor-height%/g;

        if (currentPage.height === undefined) {
            console.error(
                `[BoB] Required height property of ${
                    currentPage.title
                } is not defined`
            );
            process.exit(1);
        }

        return tmpl.replace(regex, currentPage.height);
    },
    /**
     * Sets the `<title>` and `<h4>` main page title
     * @param {Object} currentPage - The current page object
     * @param {String} tmpl - The template as a string
     *
     * @returns The processed template with the titles set
     */
    setMainTitle: function(currentPage, tmpl) {
        const regex = /%title%/g;
        let resultsArray = [];

        // replace all instances of `%title` with the `currentPage.title`
        while ((resultsArray = regex.exec(tmpl)) !== null) {
            tmpl = tmpl.replace(
                resultsArray[0].trim(),
                processor.preprocessHTML(currentPage.title)
            );
        }
        return tmpl;
    }
};
<commit_msg>Use semicolon in inlined perf code (#1103)<commit_after>'use strict';

const fse = require('fs-extra');
const uglify = require('uglify-es');

const processor = require('./processor');

module.exports = {
    /**
     * Load, minifies, and then injects the contents of
     * `js/editor-libs/perf.js` into the head of the document
     * @param {string} tmpl - The template as a string
     * @return {string} The template as a string with the perf script injected
     */
    injectPerf(tmpl) {
        const regex = /%inject-perf%/g;
        const perfJs = './js/editor-libs/perf.js';
        let minified = uglify.minify(fse.readFileSync(perfJs, 'utf-8'),
                                     {compress: {sequences: false}}).code;
        return tmpl.replace(regex, minified);
    },
    /**
     * Sets the appropriate class on the tabbed editor’s container
     * element based on the height property defined in the example’s
     * meta data
     * @param {Object} currentPage - The current page object
     * @param {String} tmpl - The template as a string
     *
     * @returns The processed template with the height class set
     */
    setEditorHeight: function(currentPage, tmpl) {
        const regex = /%editor-height%/g;

        if (currentPage.height === undefined) {
            console.error(
                `[BoB] Required height property of ${
                    currentPage.title
                } is not defined`
            );
            process.exit(1);
        }

        return tmpl.replace(regex, currentPage.height);
    },
    /**
     * Sets the `<title>` and `<h4>` main page title
     * @param {Object} currentPage - The current page object
     * @param {String} tmpl - The template as a string
     *
     * @returns The processed template with the titles set
     */
    setMainTitle: function(currentPage, tmpl) {
        const regex = /%title%/g;
        let resultsArray = [];

        // replace all instances of `%title` with the `currentPage.title`
        while ((resultsArray = regex.exec(tmpl)) !== null) {
            tmpl = tmpl.replace(
                resultsArray[0].trim(),
                processor.preprocessHTML(currentPage.title)
            );
        }
        return tmpl;
    }
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict';

const fs = require('fs');
const path = require('path');
const { runChildCmd } = require('../helpers/utils');

const env = process.env.DEPLOY_ENV || 'test';
const bucket = 'atm-deploy-caches';
const prefix = 'atm-website/npm-registry';
const cacheDir = path.join(process.env.HOME, '.npm_lazy');
const configPath = path.join(__dirname, '../../', 'npm_lazy.config.js');

/**
 * Parent message handler
 */
process.on('message', (event) => {
  switch(event.name) {
    case 'get-config': getConfig(); break;
    case 'configure': configure(); break;
    case 'run-registry': runRegistry(); break;
    case 'exit': onExit(); break;
  }
});

/**
 * Build and send config object
 */
function getConfig() {
  process.send({
    cacheDir: cacheDir,
    configPath: configPath,
    pullCommand: `aws s3 sync s3://${bucket}/${prefix} ${cacheDir} --delete`,
    pushCommand: `aws s3 sync ${cacheDir} s3://${bucket}/${prefix} --delete`
  });
}

/**
 * Run local npm registry
 */
function runRegistry() {
  runChildCmd(`npm_lazy --config ${configPath}`, /.*(Request|Reusing).*/).then(() => {
    console.log('npm_lazy server stopped');
  })
}

/**
 * Configure local registry for environment
 */
function configure() {
  runChildCmd('npm config set registry http://localhost:8080/').then(() => {
    console.log('Local npm registry configured');
  });

  if (!fs.existsSync(cacheDir)){
    fs.mkdirSync(cacheDir);
  }

  fs.writeFileSync(
    configPath,
    `module.exports = {
      loggingOpts: {
        logRequesterIP: true,
        logToConsole: true
      },
      readOnly: ${['master', 'stage'].includes(env)},
      cacheDirectory: '${cacheDir}',
      cacheAge: 9999999999,
      httpTimeout: 4000,
      maxRetries: 2,
      externalUrl: 'http://localhost:8080',
      remoteUrl: 'https://registry.npmjs.com/',
      port: 8080,
      host: '0.0.0.0',
      proxy: {}
    };`
  );
}

/**
 * Reset registry config and exit
 */
function onExit() {
  runChildCmd('npm config delete registry').then(() => {
    process.exit(0);
  });
}
<commit_msg>#ATM-WEB minor fix [skip ci]<commit_after>#!/usr/bin/env node

'use strict';

const fs = require('fs');
const path = require('path');
const { runChildCmd } = require('../helpers/utils');

const env = process.env.DEPLOY_ENV || 'test';
const bucket = 'atm-deploy-caches';
const prefix = 'atm-website/npm-registry';
const cacheDir = path.join(process.env.HOME, '.npm_lazy');
const configPath = path.join(__dirname, '../../', 'npm_lazy.config.js');

/**
 * Parent message handler
 */
process.on('message', (event) => {
  switch(event.name) {
    case 'get-config': getConfig(); break;
    case 'configure': configure(); break;
    case 'run-registry': runRegistry(); break;
    case 'exit': onExit(); break;
  }
});

/**
 * Build and send config object
 */
function getConfig() {
  process.send({
    cacheDir: cacheDir,
    configPath: configPath,
    pullCommand: `aws s3 sync s3://${bucket}/${prefix} ${cacheDir} --delete`,
    pushCommand: `aws s3 sync ${cacheDir} s3://${bucket}/${prefix} --delete`
  });
}

/**
 * Run local npm registry
 */
function runRegistry() {
  runChildCmd(`npm_lazy --config ${configPath}`, /.*(Request|Reusing).*/).then(() => {
    console.log('npm_lazy server stopped');
  })
}

/**
 * Configure local registry for environment
 */
function configure() {
  Promise.all([
    runChildCmd('npm config set registry http://localhost:8080/'),
    runChildCmd(`rm -rf ${cacheDir} && mkdir ${cacheDir}`)
  ]).then(() => {
    console.log('Local npm registry configured');
  });

  fs.writeFileSync(
    configPath,
    `module.exports = {
      loggingOpts: {
        logRequesterIP: true,
        logToConsole: true
      },
      readOnly: ${['master', 'stage'].includes(env)},
      cacheDirectory: '${cacheDir}',
      cacheAge: 9999999999,
      httpTimeout: 4000,
      maxRetries: 2,
      externalUrl: 'http://localhost:8080',
      remoteUrl: 'https://registry.npmjs.com/',
      port: 8080,
      host: '0.0.0.0',
      proxy: {}
    };`
  );
}

/**
 * Reset registry config and exit
 */
function onExit() {
  runChildCmd('npm config delete registry').then(() => {
    process.exit(0);
  });
}
<|endoftext|>


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

goog.provide('org.apache.flex.core.Application');

goog.require('org.apache.flex.core.HTMLElementWrapper');
goog.require('org.apache.flex.core.IValuesImpl');
goog.require('org.apache.flex.core.ValuesManager');
goog.require('org.apache.flex.utils.MXMLDataInterpreter');

/**
 * @constructor
 * @extends {org.apache.flex.core.HTMLElementWrapper}
 */
org.apache.flex.core.Application = function() {
  org.apache.flex.core.Application.base(this, 'constructor');
};
goog.inherits(org.apache.flex.core.Application,
    org.apache.flex.core.HTMLElementWrapper);

/**
 * Metadata
 *
 * @type {Object.<string, Array.<Object>>}
 */
org.apache.flex.core.Application.prototype.FLEXJS_CLASS_INFO =
    { names: [{ name: 'Application',
                qName: 'org.apache.flex.core.Application' }] };

/**
 * @expose
 * @type {Object}
 */
org.apache.flex.core.Application.prototype.controller = null;

/**
 * @expose
 * @type {Object}
 */
org.apache.flex.core.Application.prototype.initialView = null;

/**
 * @expose
 * @type {org.apache.flex.events.EventDispatcher}
 */
org.apache.flex.core.Application.prototype.model = null;

/**
 * @expose
 * @param {org.apache.flex.core.IValuesImpl} value The IValuesImpl.
 */
org.apache.flex.core.Application.prototype.set_valuesImpl =
    function(value) {
  org.apache.flex.core.ValuesManager.valuesImpl = value;
  if (value.init) {
    value.init(this);
  }
};

/**
 * @expose
 */
org.apache.flex.core.Application.prototype.start = function() {
  this.element = document.getElementsByTagName('body')[0];
  this.element.flexjs_wrapper = this;

  org.apache.flex.utils.MXMLDataInterpreter.generateMXMLInstances(this, null, this.get_MXMLDescriptor());

  this.dispatchEvent('initialize');

  this.initialView.applicationModel = this.model;
  this.addElement(this.initialView);

  this.dispatchEvent('viewChanged');
};

/**
 * @expose
 * @param {Array} data The data for the attributes.
 */
org.apache.flex.core.Application.prototype.generateMXMLAttributes = function(data) {
  org.apache.flex.utils.MXMLDataInterpreter.generateMXMLProperties(this, data);
};

/**
 * @param {Object} c The child element.
 */
org.apache.flex.core.Application.prototype.addElement =
    function(c) {
  this.element.appendChild(c.element);
  c.addedToParent();
};

<commit_msg>set className so CSS will apply<commit_after>/**
 * 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.
 */

goog.provide('org.apache.flex.core.Application');

goog.require('org.apache.flex.core.HTMLElementWrapper');
goog.require('org.apache.flex.core.IValuesImpl');
goog.require('org.apache.flex.core.ValuesManager');
goog.require('org.apache.flex.utils.MXMLDataInterpreter');

/**
 * @constructor
 * @extends {org.apache.flex.core.HTMLElementWrapper}
 */
org.apache.flex.core.Application = function() {
  org.apache.flex.core.Application.base(this, 'constructor');
};
goog.inherits(org.apache.flex.core.Application,
    org.apache.flex.core.HTMLElementWrapper);

/**
 * Metadata
 *
 * @type {Object.<string, Array.<Object>>}
 */
org.apache.flex.core.Application.prototype.FLEXJS_CLASS_INFO =
    { names: [{ name: 'Application',
                qName: 'org.apache.flex.core.Application' }] };

/**
 * @expose
 * @type {Object}
 */
org.apache.flex.core.Application.prototype.controller = null;

/**
 * @expose
 * @type {Object}
 */
org.apache.flex.core.Application.prototype.initialView = null;

/**
 * @expose
 * @type {org.apache.flex.events.EventDispatcher}
 */
org.apache.flex.core.Application.prototype.model = null;

/**
 * @expose
 * @param {org.apache.flex.core.IValuesImpl} value The IValuesImpl.
 */
org.apache.flex.core.Application.prototype.set_valuesImpl =
    function(value) {
  org.apache.flex.core.ValuesManager.valuesImpl = value;
  if (value.init) {
    value.init(this);
  }
};

/**
 * @expose
 */
org.apache.flex.core.Application.prototype.start = function() {
  this.element = document.getElementsByTagName('body')[0];
  this.element.flexjs_wrapper = this;
  this.element.className = "Application";

  org.apache.flex.utils.MXMLDataInterpreter.generateMXMLInstances(this, null, this.get_MXMLDescriptor());

  this.dispatchEvent('initialize');

  this.initialView.applicationModel = this.model;
  this.addElement(this.initialView);

  this.dispatchEvent('viewChanged');
};

/**
 * @expose
 * @param {Array} data The data for the attributes.
 */
org.apache.flex.core.Application.prototype.generateMXMLAttributes = function(data) {
  org.apache.flex.utils.MXMLDataInterpreter.generateMXMLProperties(this, data);
};

/**
 * @param {Object} c The child element.
 */
org.apache.flex.core.Application.prototype.addElement =
    function(c) {
  this.element.appendChild(c.element);
  c.addedToParent();
};

<|endoftext|>


<commit_before>/* -*- coding: utf-8 -*- */
/* global cforum, Mustache, t, setDismissHandlers, autohideAlerts, hasLocalstorage, uconf */

cforum.cf_threads = {
  numThreads: 0,
  numMessages: 0,
  newMessages: [],

  new: function() {
    cforum.cf_threads.initGlobal();

    cforum.tags.initTags();
    cforum.cf_threads.initCursor();

    cforum.cf_messages.initMarkdown("message_input");
    cforum.cf_messages.initUpload();
    cforum.cf_messages.initPreview("message_input");
    $("#message_input").mentions();
  },
  create: function() {
    cforum.cf_threads.initGlobal();

    cforum.tags.initTags();
    cforum.cf_messages.initMarkdown("message_input");
    cforum.cf_messages.initUpload();
    cforum.cf_messages.initPreview("message_input");
    cforum.cf_messages.initMaxLengthWarnings();
    $("#message_input").mentions();
  },

  index: function() {
    // var path = '/threads/' + (cforum.currentForum ? cforum.currentForum.slug : 'all');
    cforum.client.on('thread:create', cforum.cf_threads.newThreadArriving);

    // path = '/messages/' + (cforum.currentForum ? cforum.currentForum.slug : 'all');
    cforum.client.on('message:create', cforum.cf_threads.newMessageArriving);

    if(!cforum.currentUser) {
      cforum.cf_threads.initOpenClose();
    }
  },

  showNewAlert: function() {
    var alert = $("#new_messages_arrived");
    var append = false;

    if(!alert.length) {
      alert = $("
<button type=\"button\" class=\"close\" data-dismiss=\"cf-alert\" aria-label=\"Close\">×</button>
");
      append = true;
    }

    alert.text(Mustache.render(
      t('messages_threads'),
      {threads: cforum.cf_threads.numThreads,
       messages: cforum.cf_threads.numMessages}));

    if(append) {
      $("#alerts-container").append(alert);
      setDismissHandlers();
      autohideAlerts();
    }
  },

  showNewThread: function(message) {
    var sortMethod = uconf('sort_threads');

    if(sortMethod != 'ascending' && sortMethod != 'descending' && sortMethod != 'newest-first') {
      sortMethod = 'descending';
    }

    var url = cforum.baseUrl +
          (cforum.currentForum ? cforum.currentForum.slug : 'all') +
          message.thread.slug;

    $.get(url).
      done(function(data) {
        switch(sortMethod) {
        case 'newest-first':
        case 'descending':
          if(document.location.href.indexOf('p=0') != -1 || document.location.href.indexOf('p=') == -1) {
            var sticky = $("[data-js=threadlist] .sticky:last");
            if(sticky.length === 0) {
              $("[data-js=threadlist]").prepend(data);
            }
            else {
              sticky.after(data);
            }
          }
          break;

        case 'ascending':
          if($(".cf-pages .last").hasClass('disabled')) {
            $("[data-js=threadlist]").append(data);
          }
          break;
        }

        cforum.cf_threads.newMessages.push(message.message.message_id);

        var m;
        for(var i = 0; i < cforum.cf_threads.newMessages.length; ++i) {
          m = $("#m" + cforum.cf_threads.newMessages[i]);
          if(!m.hasClass('new')) {
            m.addClass('new');
          }
        }
      });
  },

  newThreadArriving: function(message) {
    cforum.cf_threads.numThreads += 1;
    cforum.cf_threads.numMessages += 1;

    if(cforum.currentUser && message.message.user_id == cforum.currentUser.user_id) {
      return;
    }

    if(uconf('load_messages_via_js') != 'no') {
      cforum.cf_threads.showNewThread(message);
    }

    cforum.cf_threads.showNewAlert();
    cforum.updateFavicon();
  },

  newMessageArriving: function(message) {
    cforum.cf_threads.numMessages += 1;

    if(cforum.currentUser && message.message.user_id == cforum.currentUser.user_id) {
      return;
    }

    cforum.cf_threads.showNewAlert();

    if(uconf('load_messages_via_js') != 'no') {
      var url = cforum.baseUrl +
            (cforum.currentForum ? cforum.currentForum.slug : 'all') +
            message.thread.slug;

      $.get(url).
        done(function(data) {
          $("#t" + message.thread.thread_id).replaceWith(data);

          if(uconf('sort_threads') == 'newest-first') {
            var sticky = $("[data-js=threadlist] .sticky:last");
            if(sticky.length === 0) {
              $("[data-js=threadlist]").prepend($("#t" + message.thread.thread_id));
            }
            else {
              sticky.after($("#t" + message.thread.thread_id));
            }
          }

          cforum.cf_threads.newMessages.push(message.message.message_id);
          var m;

          for(var i = 0; i < cforum.cf_threads.newMessages.length; ++i) {
            m = $("#m" + cforum.cf_threads.newMessages[i]);
            if(!m.hasClass('new')) {
              m.addClass('new');
            }
          }
        });
    }

    cforum.updateFavicon();
  },

  initGlobal: function() {
    if(!cforum.currentForum) {
      $("#cf_thread_forum_id").on('change', function() {
        var val = $(this).val();

        for(var i = 0; i < cforum.forums.length; ++i) {
          if(cforum.forums[i].forum_id == val) {
            cforum.currentForum = cforum.forums[i];
            break;
          }
        }
      });
      $("#cf_thread_forum_id").trigger('change');
    }
  },

  initCursor: function() {
    var content = $("#message_input");
    var subj = $("#cf_thread_message_subject");
    var author = $("#cf_thread_message_author");

    cforum.cf_threads.setCursor(author, subj, content);
  },

  setCursor: function(author, subject, content) {
    if(!subject.val()) {
      setTimeout(function() { subject.focus(); }, 0);
    }
    else {
      if(cforum.currentUser) {
        setTimeout(function() { content.focus(); }, 0);
        cforum.cf_threads.setCursorInContent(content);
      }
      else {
        if(!author.val()) {
          setTimeout(function() { author.focus(); }, 0);
        }
        else {
          setTimeout(function() { content.focus(); }, 0);
          cforum.cf_threads.setCursorInContent(content);
        }
      }
    }
  },

  setCursorInContent: function(content) {
    var cnt = content.val();
    var i;

    for(i = 0; i < cnt.length; ++i) {
      if(cnt.substr(i, 1) == '>' &&
         (i === 0 || cnt.substr(i - 1, 1) == "\n") &&
         cnt.substr(i + 1, 1) == ' ') {
        content.setSelection(i, i);
        return;
      }
    }

    // we couldn't find a quote, so we set cursor after the first empty line
    var newline = 0;
    for(i = 0; i < cnt.length; ++i) {
      if(cnt.substr(i - 1, 1) == "\012") {
        newline++;
      }
      else if(cnt.substr(i - 1, 1) == "\015") {
        continue;
      }
      else {
        newline = 0;
      }

      if(newline == 2) {
        content.setSelection(i, i);
        return;
      }
    }
  },

  initOpenClose: function() {
    $("#link-archiv").after('
' + t('close_all_threads') + "
");
    $("div[data-js=threadlist] .thread > header").
      prepend(" ");

    $("div[data-js=threadlist] .thread > header > i").
      click(cforum.cf_threads.toggleThread);

    $("#open-close-all-threads").click(cforum.cf_threads.toggleAllThreads);

    if(hasLocalstorage()) {
      var has_open = false;

      $("div[data-js=threadlist] .thread").each(function() {
        var $this = $(this);
        var id = $this.attr('id');

        if(localStorage['closed-' + id]) {
          $this.children("ol").css('display', 'none');
          $this.find("header > i.icon-thread").
            removeClass("open").
            addClass('closed');
        }
        else {
          has_open = true;
        }
      });

      if(!has_open) {
        $("#open-close-all-threads a").text(t('open_all_threads'));
        $("#open-close-all-threads").
          removeClass("close-all").
          addClass("open-all");
      }
    }
  },

  toggleThread: function() {
    var $this = $(this);
    var elem = $this.closest("article");

    if($this.hasClass('open')) {
      $this.removeClass("open").addClass('closed');
      elem.children("ol").slideUp('fast');

      if(hasLocalstorage()) {
        localStorage['closed-' + elem.attr('id')] = true;
      }
    }
    else {
      $this.removeClass("closed").addClass('open');
      elem.children("ol").slideDown('fast');

      if(hasLocalstorage()) {
        localStorage.removeItem('closed-' + elem.attr('id'));
      }
    }
  },

  toggleAllThreads: function(ev) {
    ev.preventDefault();

    if($(this).hasClass('open-all')) {
      $("div[data-js=threadlist] .thread > ol").
        css('display', 'block');
      $("div[data-js=threadlist] .thread > header > i").
        addClass('open').
        removeClass("closed");

      $("#open-close-all-threads a").text(t('close_all_threads'));
      $("#open-close-all-threads").
        removeClass("open-all").
        addClass("close-all");

      if(hasLocalstorage()) {
        $("div[data-js=threadlist] .thread").each(function() {
          localStorage.removeItem('closed-' + $(this).attr('id'));
        });
      }
    }
    else {
      $("div[data-js=threadlist] .thread > ol").
        css('display', 'none');
      $("div[data-js=threadlist] .thread > header > i").
        addClass('closed').
        removeClass("open");

      $("#open-close-all-threads a").text(t('open_all_threads'));
      $("#open-close-all-threads").
        removeClass("close-all").
        addClass("open-all");

      if(hasLocalstorage()) {
        $("div[data-js=threadlist] .thread").each(function() {
          localStorage['closed-' + $(this).attr('id')] = true;
        });
      }
    }
  }
};

/* eof */
<commit_msg>fix: check length on new threads as well<commit_after>/* -*- coding: utf-8 -*- */
/* global cforum, Mustache, t, setDismissHandlers, autohideAlerts, hasLocalstorage, uconf */

cforum.cf_threads = {
  numThreads: 0,
  numMessages: 0,
  newMessages: [],

  new: function() {
    cforum.cf_threads.initGlobal();

    cforum.tags.initTags();
    cforum.cf_threads.initCursor();

    cforum.cf_messages.initMarkdown("message_input");
    cforum.cf_messages.initUpload();
    cforum.cf_messages.initPreview("message_input");
    cforum.cf_messages.initMaxLengthWarnings();
    $("#message_input").mentions();
  },
  create: function() {
    cforum.cf_threads.initGlobal();

    cforum.tags.initTags();
    cforum.cf_messages.initMarkdown("message_input");
    cforum.cf_messages.initUpload();
    cforum.cf_messages.initPreview("message_input");
    cforum.cf_messages.initMaxLengthWarnings();
    $("#message_input").mentions();
  },

  index: function() {
    // var path = '/threads/' + (cforum.currentForum ? cforum.currentForum.slug : 'all');
    cforum.client.on('thread:create', cforum.cf_threads.newThreadArriving);

    // path = '/messages/' + (cforum.currentForum ? cforum.currentForum.slug : 'all');
    cforum.client.on('message:create', cforum.cf_threads.newMessageArriving);

    if(!cforum.currentUser) {
      cforum.cf_threads.initOpenClose();
    }
  },

  showNewAlert: function() {
    var alert = $("#new_messages_arrived");
    var append = false;

    if(!alert.length) {
      alert = $("
<button type=\"button\" class=\"close\" data-dismiss=\"cf-alert\" aria-label=\"Close\">×</button>
");
      append = true;
    }

    alert.text(Mustache.render(
      t('messages_threads'),
      {threads: cforum.cf_threads.numThreads,
       messages: cforum.cf_threads.numMessages}));

    if(append) {
      $("#alerts-container").append(alert);
      setDismissHandlers();
      autohideAlerts();
    }
  },

  showNewThread: function(message) {
    var sortMethod = uconf('sort_threads');

    if(sortMethod != 'ascending' && sortMethod != 'descending' && sortMethod != 'newest-first') {
      sortMethod = 'descending';
    }

    var url = cforum.baseUrl +
          (cforum.currentForum ? cforum.currentForum.slug : 'all') +
          message.thread.slug;

    $.get(url).
      done(function(data) {
        switch(sortMethod) {
        case 'newest-first':
        case 'descending':
          if(document.location.href.indexOf('p=0') != -1 || document.location.href.indexOf('p=') == -1) {
            var sticky = $("[data-js=threadlist] .sticky:last");
            if(sticky.length === 0) {
              $("[data-js=threadlist]").prepend(data);
            }
            else {
              sticky.after(data);
            }
          }
          break;

        case 'ascending':
          if($(".cf-pages .last").hasClass('disabled')) {
            $("[data-js=threadlist]").append(data);
          }
          break;
        }

        cforum.cf_threads.newMessages.push(message.message.message_id);

        var m;
        for(var i = 0; i < cforum.cf_threads.newMessages.length; ++i) {
          m = $("#m" + cforum.cf_threads.newMessages[i]);
          if(!m.hasClass('new')) {
            m.addClass('new');
          }
        }
      });
  },

  newThreadArriving: function(message) {
    cforum.cf_threads.numThreads += 1;
    cforum.cf_threads.numMessages += 1;

    if(cforum.currentUser && message.message.user_id == cforum.currentUser.user_id) {
      return;
    }

    if(uconf('load_messages_via_js') != 'no') {
      cforum.cf_threads.showNewThread(message);
    }

    cforum.cf_threads.showNewAlert();
    cforum.updateFavicon();
  },

  newMessageArriving: function(message) {
    cforum.cf_threads.numMessages += 1;

    if(cforum.currentUser && message.message.user_id == cforum.currentUser.user_id) {
      return;
    }

    cforum.cf_threads.showNewAlert();

    if(uconf('load_messages_via_js') != 'no') {
      var url = cforum.baseUrl +
            (cforum.currentForum ? cforum.currentForum.slug : 'all') +
            message.thread.slug;

      $.get(url).
        done(function(data) {
          $("#t" + message.thread.thread_id).replaceWith(data);

          if(uconf('sort_threads') == 'newest-first') {
            var sticky = $("[data-js=threadlist] .sticky:last");
            if(sticky.length === 0) {
              $("[data-js=threadlist]").prepend($("#t" + message.thread.thread_id));
            }
            else {
              sticky.after($("#t" + message.thread.thread_id));
            }
          }

          cforum.cf_threads.newMessages.push(message.message.message_id);
          var m;

          for(var i = 0; i < cforum.cf_threads.newMessages.length; ++i) {
            m = $("#m" + cforum.cf_threads.newMessages[i]);
            if(!m.hasClass('new')) {
              m.addClass('new');
            }
          }
        });
    }

    cforum.updateFavicon();
  },

  initGlobal: function() {
    if(!cforum.currentForum) {
      $("#cf_thread_forum_id").on('change', function() {
        var val = $(this).val();

        for(var i = 0; i < cforum.forums.length; ++i) {
          if(cforum.forums[i].forum_id == val) {
            cforum.currentForum = cforum.forums[i];
            break;
          }
        }
      });
      $("#cf_thread_forum_id").trigger('change');
    }
  },

  initCursor: function() {
    var content = $("#message_input");
    var subj = $("#cf_thread_message_subject");
    var author = $("#cf_thread_message_author");

    cforum.cf_threads.setCursor(author, subj, content);
  },

  setCursor: function(author, subject, content) {
    if(!subject.val()) {
      setTimeout(function() { subject.focus(); }, 0);
    }
    else {
      if(cforum.currentUser) {
        setTimeout(function() { content.focus(); }, 0);
        cforum.cf_threads.setCursorInContent(content);
      }
      else {
        if(!author.val()) {
          setTimeout(function() { author.focus(); }, 0);
        }
        else {
          setTimeout(function() { content.focus(); }, 0);
          cforum.cf_threads.setCursorInContent(content);
        }
      }
    }
  },

  setCursorInContent: function(content) {
    var cnt = content.val();
    var i;

    for(i = 0; i < cnt.length; ++i) {
      if(cnt.substr(i, 1) == '>' &&
         (i === 0 || cnt.substr(i - 1, 1) == "\n") &&
         cnt.substr(i + 1, 1) == ' ') {
        content.setSelection(i, i);
        return;
      }
    }

    // we couldn't find a quote, so we set cursor after the first empty line
    var newline = 0;
    for(i = 0; i < cnt.length; ++i) {
      if(cnt.substr(i - 1, 1) == "\012") {
        newline++;
      }
      else if(cnt.substr(i - 1, 1) == "\015") {
        continue;
      }
      else {
        newline = 0;
      }

      if(newline == 2) {
        content.setSelection(i, i);
        return;
      }
    }
  },

  initOpenClose: function() {
    $("#link-archiv").after('
' + t('close_all_threads') + "
");
    $("div[data-js=threadlist] .thread > header").
      prepend(" ");

    $("div[data-js=threadlist] .thread > header > i").
      click(cforum.cf_threads.toggleThread);

    $("#open-close-all-threads").click(cforum.cf_threads.toggleAllThreads);

    if(hasLocalstorage()) {
      var has_open = false;

      $("div[data-js=threadlist] .thread").each(function() {
        var $this = $(this);
        var id = $this.attr('id');

        if(localStorage['closed-' + id]) {
          $this.children("ol").css('display', 'none');
          $this.find("header > i.icon-thread").
            removeClass("open").
            addClass('closed');
        }
        else {
          has_open = true;
        }
      });

      if(!has_open) {
        $("#open-close-all-threads a").text(t('open_all_threads'));
        $("#open-close-all-threads").
          removeClass("close-all").
          addClass("open-all");
      }
    }
  },

  toggleThread: function() {
    var $this = $(this);
    var elem = $this.closest("article");

    if($this.hasClass('open')) {
      $this.removeClass("open").addClass('closed');
      elem.children("ol").slideUp('fast');

      if(hasLocalstorage()) {
        localStorage['closed-' + elem.attr('id')] = true;
      }
    }
    else {
      $this.removeClass("closed").addClass('open');
      elem.children("ol").slideDown('fast');

      if(hasLocalstorage()) {
        localStorage.removeItem('closed-' + elem.attr('id'));
      }
    }
  },

  toggleAllThreads: function(ev) {
    ev.preventDefault();

    if($(this).hasClass('open-all')) {
      $("div[data-js=threadlist] .thread > ol").
        css('display', 'block');
      $("div[data-js=threadlist] .thread > header > i").
        addClass('open').
        removeClass("closed");

      $("#open-close-all-threads a").text(t('close_all_threads'));
      $("#open-close-all-threads").
        removeClass("open-all").
        addClass("close-all");

      if(hasLocalstorage()) {
        $("div[data-js=threadlist] .thread").each(function() {
          localStorage.removeItem('closed-' + $(this).attr('id'));
        });
      }
    }
    else {
      $("div[data-js=threadlist] .thread > ol").
        css('display', 'none');
      $("div[data-js=threadlist] .thread > header > i").
        addClass('closed').
        removeClass("open");

      $("#open-close-all-threads a").text(t('open_all_threads'));
      $("#open-close-all-threads").
        removeClass("close-all").
        addClass("open-all");

      if(hasLocalstorage()) {
        $("div[data-js=threadlist] .thread").each(function() {
          localStorage['closed-' + $(this).attr('id')] = true;
        });
      }
    }
  }
};

/* eof */
<|endoftext|>


<commit_before>/** @jsx m */

"use strict";
require("./LoginPage.scss");

var _ = require("underscore");
var m = require("mithril");

var OnUnload = require("../utils/OnUnload.js");
var Layout = require("../layouts/FullLayout.js");

var LoginPage = {};

LoginPage.controller = function(options) {
  OnUnload(this);
  this.controllers.layout = new Layout.controller(_.extend({id: "LoginPage"}, options));
};

LoginPage.view = function(ctrl) {
  var content = (

Please use one of your social networking accounts to log into Curate Science:

Login with Google+

Our Beta is currently by invitation only.
 Please sign up to be notified when our public Beta is ready.

        <form action="http://christianbattista.us7.list-manage.com/subscribe/post?u=d140eca9cfe4a96473dac6ea5&id=fba08af7dd" method="post" target="_blank">
          <input type="email" value="" ref="email" name="EMAIL" placeholder="Enter email address" size="30" required />

            <input type="text" name="b_d140eca9cfe4a96473dac6ea5_fba08af7dd" value="" />

          <button type="submit" className="btn">Request invite</button>
        </form>

  );

  return new Layout.view(ctrl.controllers.layout, content);
};

module.exports = LoginPage;
<commit_msg>change button text from Register to Sign Up<commit_after>/** @jsx m */

"use strict";
require("./LoginPage.scss");

var _ = require("underscore");
var m = require("mithril");

var OnUnload = require("../utils/OnUnload.js");
var Layout = require("../layouts/FullLayout.js");

var LoginPage = {};

LoginPage.controller = function(options) {
  OnUnload(this);
  this.controllers.layout = new Layout.controller(_.extend({id: "LoginPage"}, options));
};

LoginPage.view = function(ctrl) {
  var content = (

Please use one of your social networking accounts to log into Curate Science:

Login with Google+

Our Beta is currently by invitation only.
 Please sign up to be notified when our public Beta is ready.

        <form action="http://christianbattista.us7.list-manage.com/subscribe/post?u=d140eca9cfe4a96473dac6ea5&id=fba08af7dd" method="post" target="_blank">
          <input type="email" value="" ref="email" name="EMAIL" placeholder="Enter email address" size="30" required />

            <input type="text" name="b_d140eca9cfe4a96473dac6ea5_fba08af7dd" value="" />

          <button type="submit" className="btn">Sign Up</button>
        </form>

  );

  return new Layout.view(ctrl.controllers.layout, content);
};

module.exports = LoginPage;
<|endoftext|>