<commit_before>/**
 * Visual Blocks Language
 *
 * Copyright 2012 Google Inc.
 * http://blockly.googlecode.com/
 *
 * 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.
 */

/**
 * @fileoverview Helper functions for generating Dart for blocks.
 * @author fraser@google.com (Neil Fraser)
 */
'use strict';

Blockly.Dart = Blockly.Generator.get('Dart');

/**
 * List of illegal variable names.
 * This is not intended to be a security feature.  Blockly is 100% client-side,
 * so bypassing this list is trivial.  This is intended to prevent users from
 * accidentally clobbering a built-in object or function.
 * @private
 */
Blockly.Dart.addReservedWords(
    // http://www.dartlang.org/docs/spec/latest/dart-language-specification.pdf
    // Section 15.1.1
    'assert,break,case,catch,class,const,continue,default,do,else,extends,false,final,finally,for,if,in,is,new,null,return,super,switch,this,throw,true,try,var,void,while,' +
    // http://api.dartlang.org/dart_core.html
    'AbstractClassInstantiationError,ArgumentError,AssertionError,bool,CastError,Collection,Comparable,Completer,Date,double,Duration,Error,Expando,Expect,FallThroughError,Function,Future,Futures,Hashable,HashSet,int,Iterable,Iterator,Match,NoSuchMethodError,num,Object,Options,Pattern,Queue,RuntimeError,Set,Stopwatch,StringBuffer,Strings,Type,TypeError,HashMap,LinkedHashMap,List,Map,RegExp,String,Comparator,ClosureArgumentMismatchException,EmptyQueueException,Exception,ExpectException,FormatException,FutureAlreadyCompleteException,FutureNotCompleteException,IllegalAccessException,IllegalArgumentException,IllegalJSRegExpException,IndexOutOfRangeException,IntegerDivisionByZeroException,NoMoreElementsException,NotImplementedException,NullPointerException,ObjectNotClosureException,OutOfMemoryException,StackOverflowException,UnsupportedOperationException,WrongArgumentCountException');

/**
 * Order of operation ENUMs.
 * http://www.dartlang.org/docs/dart-up-and-running/ch02.html#operator_table
 */
Blockly.Dart.ORDER_ATOMIC = 0;         // 0 "" ...
Blockly.Dart.ORDER_UNARY_POSTFIX = 1;  // expr++ expr-- () [] .
Blockly.Dart.ORDER_UNARY_PREFIX = 2;   // -expr !expr ~expr ++expr --expr
Blockly.Dart.ORDER_MULTIPLICATIVE = 3; // * / % ~/
Blockly.Dart.ORDER_ADDITIVE = 4;       // + -
Blockly.Dart.ORDER_SHIFT = 5;          // << >>
Blockly.Dart.ORDER_RELATIONAL = 6;     // is is! >= > <= <
Blockly.Dart.ORDER_EQUALITY = 7;       // == != === !==
Blockly.Dart.ORDER_BITWISE_AND = 8;    // &
Blockly.Dart.ORDER_BITWISE_XOR = 9;    // ^
Blockly.Dart.ORDER_BITWISE_OR = 10;    // |
Blockly.Dart.ORDER_LOGICAL_AND = 11;   // &&
Blockly.Dart.ORDER_LOGICAL_OR = 12;    // ||
Blockly.Dart.ORDER_CONDITIONAL = 13;   // expr ? expr : expr
Blockly.Dart.ORDER_ASSIGNMENT = 14;    // = *= /= ~/= %= += -= <<= >>= &= ^= |=
Blockly.Dart.ORDER_NONE = 99;          // (...)

/**
 * Arbitrary code to inject into locations that risk causing infinite loops.
 * Any instances of '%1' will be replaced by the block ID that failed.
 * E.g. '  checkTimeout(%1);\n'
 * @type ?string
 */
Blockly.Dart.INFINITE_LOOP_TRAP = null;

/**
 * Initialise the database of variable names.
 */
Blockly.Dart.init = function() {
  // Create a dictionary of definitions to be printed before the code.
  Blockly.Dart.definitions_ = {};

  if (Blockly.Variables) {
    if (!Blockly.Dart.variableDB_) {
      Blockly.Dart.variableDB_ =
          new Blockly.Names(Blockly.Dart.RESERVED_WORDS_);
    } else {
      Blockly.Dart.variableDB_.reset();
    }

    var defvars = [];
    var variables = Blockly.Variables.allVariables();
    for (var x = 0; x < variables.length; x++) {
      defvars[x] = 'var ' +
          Blockly.Dart.variableDB_.getName(variables[x],
          Blockly.Variables.NAME_TYPE) + ';';
    }
    Blockly.Dart.definitions_['variables'] = defvars.join('\n');
  }
};

/**
 * Prepend the generated code with the variable definitions.
 * @param {string} code Generated code.
 * @return {string} Completed code.
 */
Blockly.Dart.finish = function(code) {
  // Indent every line.
  code = '  ' + code.replace(/\n/g, '\n  ');
  code = code.replace(/\n\s+$/, '\n');
  code = 'main() {\n' + code + '}';

  // Convert the definitions dictionary into a list.
  var imports = [];
  var definitions = [];
  for (var name in Blockly.Dart.definitions_) {
    var def = Blockly.Dart.definitions_[name];
    if (def.match(/^import\s/)) {
      imports.push(def);
    } else {
      definitions.push(def);
    }
  }
  var allDefs = imports.join('\n') + '\n\n' + definitions.join('\n\n');
  return allDefs.replace(/\n\n+/g, '\n\n').replace(/\n*$/, '\n\n\n') + code;
};

/**
 * Naked values are top-level blocks with outputs that aren't plugged into
 * anything.  A trailing semicolon is needed to make this legal.
 * @param {string} line Line of generated code.
 * @return {string} Legal line of code.
 */
Blockly.Dart.scrubNakedValue = function(line) {
  return line + ';\n';
};

/**
 * Encode a string as a properly escaped Dart string, complete with quotes.
 * @param {string} string Text to encode.
 * @return {string} Dart string.
 * @private
 */
Blockly.Dart.quote_ = function(string) {
  // TODO: This is a quick hack.  Replace with goog.string.quote
  string = string.replace(/\\/g, '\\\\')
                 .replace(/\n/g, '\\\n')
                 .replace(/\$/g, '\\$')
                 .replace(/'/g, '\\\'');
  return '\'' + string + '\'';
};

/**
 * Common tasks for generating Dart from blocks.
 * Handles comments for the specified block and any connected value blocks.
 * Calls any statements following this block.
 * @param {!Blockly.Block} block The current block.
 * @param {string} code The Dart code created for this block.
 * @return {string} Dart code with comments and subsequent blocks added.
 * @this {Blockly.CodeGenerator}
 * @private
 */
Blockly.Dart.scrub_ = function(block, code) {
  if (code === null) {
    // Block has handled code generation itself.
    return '';
  }
  var commentCode = '';
  // Only collect comments for blocks that aren't inline.
  if (!block.outputConnection || !block.outputConnection.targetConnection) {
    // Collect comment for this block.
    var comment = block.getCommentText();
    if (comment) {
      commentCode += Blockly.Generator.prefixLines(comment, '// ') + '\n';
    }
    // Collect comments for all value arguments.
    // Don't collect comments for nested statements.
    for (var x = 0; x < block.inputList.length; x++) {
      if (block.inputList[x].type == Blockly.INPUT_VALUE) {
        var childBlock = block.inputList[x].connection.targetBlock();
        if (childBlock) {
          var comment = Blockly.Generator.allNestedComments(childBlock);
          if (comment) {
            commentCode += Blockly.Generator.prefixLines(comment, '// ');
          }
        }
      }
    }
  }
  var nextBlock = block.nextConnection && block.nextConnection.targetBlock();
  var nextCode = this.blockToCode(nextBlock);
  return commentCode + code + nextCode;
};
<commit_msg>Update Dart's list of reserved words.<commit_after>/**
 * Visual Blocks Language
 *
 * Copyright 2012 Google Inc.
 * http://blockly.googlecode.com/
 *
 * 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.
 */

/**
 * @fileoverview Helper functions for generating Dart for blocks.
 * @author fraser@google.com (Neil Fraser)
 */
'use strict';

Blockly.Dart = Blockly.Generator.get('Dart');

/**
 * List of illegal variable names.
 * This is not intended to be a security feature.  Blockly is 100% client-side,
 * so bypassing this list is trivial.  This is intended to prevent users from
 * accidentally clobbering a built-in object or function.
 * @private
 */
Blockly.Dart.addReservedWords(
    // http://www.dartlang.org/docs/spec/latest/dart-language-specification.pdf
    // Section 16.1.1
    'assert,break,case,catch,class,const,continue,default,do,else,extends,false,final,finally,for,if,in,is,new,null,return,super,switch,this,throw,true,try,var,void,while,with,' +
    // http://api.dartlang.org/dart_core.html
    'Collection,Comparable,Completer,Date,double,Function,Future,Hashable,HashMap,HashSet,int,InvocationMirror,Iterable,Iterator,LinkedHashMap,List,Map,Match,num,Options,Pattern,Queue,RegExp,Sequence,SequenceCollection,Set,Stopwatch,String,StringBuffer,Strings,Type,bool,DoubleLinkedQueue,DoubleLinkedQueueEntry,Duration,Expando,Expect,Futures,Object,SequenceIterator,SequenceList,Comparator,AbstractClassInstantiationError,ArgumentError,AssertionError,CastError,Error,Exception,ExpectException,FallThroughError,FormatException,FutureAlreadyCompleteException,FutureNotCompleteException,FutureUnhandledException,IllegalJSRegExpException,IntegerDivisionByZeroException,NoSuchMethodError,NullThrownError,OutOfMemoryError,RangeError,RuntimeError,StackOverflowError,StateError,TypeError,UnimplementedError,UnsupportedError');
/**
 * Order of operation ENUMs.
 * http://www.dartlang.org/docs/dart-up-and-running/ch02.html#operator_table
 */
Blockly.Dart.ORDER_ATOMIC = 0;         // 0 "" ...
Blockly.Dart.ORDER_UNARY_POSTFIX = 1;  // expr++ expr-- () [] .
Blockly.Dart.ORDER_UNARY_PREFIX = 2;   // -expr !expr ~expr ++expr --expr
Blockly.Dart.ORDER_MULTIPLICATIVE = 3; // * / % ~/
Blockly.Dart.ORDER_ADDITIVE = 4;       // + -
Blockly.Dart.ORDER_SHIFT = 5;          // << >>
Blockly.Dart.ORDER_RELATIONAL = 6;     // is is! >= > <= <
Blockly.Dart.ORDER_EQUALITY = 7;       // == != === !==
Blockly.Dart.ORDER_BITWISE_AND = 8;    // &
Blockly.Dart.ORDER_BITWISE_XOR = 9;    // ^
Blockly.Dart.ORDER_BITWISE_OR = 10;    // |
Blockly.Dart.ORDER_LOGICAL_AND = 11;   // &&
Blockly.Dart.ORDER_LOGICAL_OR = 12;    // ||
Blockly.Dart.ORDER_CONDITIONAL = 13;   // expr ? expr : expr
Blockly.Dart.ORDER_ASSIGNMENT = 14;    // = *= /= ~/= %= += -= <<= >>= &= ^= |=
Blockly.Dart.ORDER_NONE = 99;          // (...)

/**
 * Arbitrary code to inject into locations that risk causing infinite loops.
 * Any instances of '%1' will be replaced by the block ID that failed.
 * E.g. '  checkTimeout(%1);\n'
 * @type ?string
 */
Blockly.Dart.INFINITE_LOOP_TRAP = null;

/**
 * Initialise the database of variable names.
 */
Blockly.Dart.init = function() {
  // Create a dictionary of definitions to be printed before the code.
  Blockly.Dart.definitions_ = {};

  if (Blockly.Variables) {
    if (!Blockly.Dart.variableDB_) {
      Blockly.Dart.variableDB_ =
          new Blockly.Names(Blockly.Dart.RESERVED_WORDS_);
    } else {
      Blockly.Dart.variableDB_.reset();
    }

    var defvars = [];
    var variables = Blockly.Variables.allVariables();
    for (var x = 0; x < variables.length; x++) {
      defvars[x] = 'var ' +
          Blockly.Dart.variableDB_.getName(variables[x],
          Blockly.Variables.NAME_TYPE) + ';';
    }
    Blockly.Dart.definitions_['variables'] = defvars.join('\n');
  }
};

/**
 * Prepend the generated code with the variable definitions.
 * @param {string} code Generated code.
 * @return {string} Completed code.
 */
Blockly.Dart.finish = function(code) {
  // Indent every line.
  code = '  ' + code.replace(/\n/g, '\n  ');
  code = code.replace(/\n\s+$/, '\n');
  code = 'main() {\n' + code + '}';

  // Convert the definitions dictionary into a list.
  var imports = [];
  var definitions = [];
  for (var name in Blockly.Dart.definitions_) {
    var def = Blockly.Dart.definitions_[name];
    if (def.match(/^import\s/)) {
      imports.push(def);
    } else {
      definitions.push(def);
    }
  }
  var allDefs = imports.join('\n') + '\n\n' + definitions.join('\n\n');
  return allDefs.replace(/\n\n+/g, '\n\n').replace(/\n*$/, '\n\n\n') + code;
};

/**
 * Naked values are top-level blocks with outputs that aren't plugged into
 * anything.  A trailing semicolon is needed to make this legal.
 * @param {string} line Line of generated code.
 * @return {string} Legal line of code.
 */
Blockly.Dart.scrubNakedValue = function(line) {
  return line + ';\n';
};

/**
 * Encode a string as a properly escaped Dart string, complete with quotes.
 * @param {string} string Text to encode.
 * @return {string} Dart string.
 * @private
 */
Blockly.Dart.quote_ = function(string) {
  // TODO: This is a quick hack.  Replace with goog.string.quote
  string = string.replace(/\\/g, '\\\\')
                 .replace(/\n/g, '\\\n')
                 .replace(/\$/g, '\\$')
                 .replace(/'/g, '\\\'');
  return '\'' + string + '\'';
};

/**
 * Common tasks for generating Dart from blocks.
 * Handles comments for the specified block and any connected value blocks.
 * Calls any statements following this block.
 * @param {!Blockly.Block} block The current block.
 * @param {string} code The Dart code created for this block.
 * @return {string} Dart code with comments and subsequent blocks added.
 * @this {Blockly.CodeGenerator}
 * @private
 */
Blockly.Dart.scrub_ = function(block, code) {
  if (code === null) {
    // Block has handled code generation itself.
    return '';
  }
  var commentCode = '';
  // Only collect comments for blocks that aren't inline.
  if (!block.outputConnection || !block.outputConnection.targetConnection) {
    // Collect comment for this block.
    var comment = block.getCommentText();
    if (comment) {
      commentCode += Blockly.Generator.prefixLines(comment, '// ') + '\n';
    }
    // Collect comments for all value arguments.
    // Don't collect comments for nested statements.
    for (var x = 0; x < block.inputList.length; x++) {
      if (block.inputList[x].type == Blockly.INPUT_VALUE) {
        var childBlock = block.inputList[x].connection.targetBlock();
        if (childBlock) {
          var comment = Blockly.Generator.allNestedComments(childBlock);
          if (comment) {
            commentCode += Blockly.Generator.prefixLines(comment, '// ');
          }
        }
      }
    }
  }
  var nextBlock = block.nextConnection && block.nextConnection.targetBlock();
  var nextCode = this.blockToCode(nextBlock);
  return commentCode + code + nextCode;
};
<|endoftext|>


<commit_before>/**
 * @license
 * Visual Blocks Language
 *
 * Copyright 2012 Google Inc.
 * https://blockly.googlecode.com/
 *
 * 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.
 */

/**
 * @fileoverview Helper functions for generating JavaScript for blocks.
 * @author fraser@google.com (Neil Fraser)
 */
'use strict';

goog.provide('Blockly.Java');

goog.require('Blockly.Generator');

Blockly.Java = new Blockly.Generator('Java');

/**
 * List of illegal variable names.
 * This is not intended to be a security feature.  Blockly is 100% client-side,
 * so bypassing this list is trivial.  This is intended to prevent users from
 * accidentally clobbering a built-in object or function.
 * @private
 */
Blockly.Java.addReservedWords(
  //http://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html
  'abstract,continue,for,new,switch,assert,default,goto,package,synchronized' +
  'boolean,do,if,private,this,break,double,implements,protected,throw,byte,else'+
  'import,public,throws,case,enum,instanceof,return,transient,catch,extends,int'+
  'short,try,char,final,interface,static,void,class,finally,long,strictfp'+
  'volatile,const,float,native,super,while'
);

/**
 * Order of operation ENUMs.
 * https://developer.mozilla.org/en/JavaScript/Reference/Operators/Operator_Precedence
 * @todo Update for Java
 */
Blockly.Java.ORDER_ATOMIC = 0;         // 0 "" ...
Blockly.Java.ORDER_MEMBER = 1;         // . []
Blockly.Java.ORDER_NEW = 1;            // new
Blockly.Java.ORDER_FUNCTION_CALL = 2;  // ()
Blockly.Java.ORDER_INCREMENT = 3;      // ++
Blockly.Java.ORDER_DECREMENT = 3;      // --
Blockly.Java.ORDER_LOGICAL_NOT = 4;    // !
Blockly.Java.ORDER_BITWISE_NOT = 4;    // ~
Blockly.Java.ORDER_UNARY_PLUS = 4;     // +
Blockly.Java.ORDER_UNARY_NEGATION = 4; // -
Blockly.Java.ORDER_TYPEOF = 4;         // typeof
Blockly.Java.ORDER_VOID = 4;           // void
Blockly.Java.ORDER_DELETE = 4;         // delete
Blockly.Java.ORDER_MULTIPLICATION = 5; // *
Blockly.Java.ORDER_DIVISION = 5;       // /
Blockly.Java.ORDER_MODULUS = 5;        // %
Blockly.Java.ORDER_ADDITION = 6;       // +
Blockly.Java.ORDER_SUBTRACTION = 6;    // -
Blockly.Java.ORDER_BITWISE_SHIFT = 7;  // << >> >>>
Blockly.Java.ORDER_RELATIONAL = 8;     // < <= > >=
Blockly.Java.ORDER_IN = 8;             // in
Blockly.Java.ORDER_INSTANCEOF = 8;     // instanceof
Blockly.Java.ORDER_EQUALITY = 9;       // == != === !==
Blockly.Java.ORDER_BITWISE_AND = 10;   // &
Blockly.Java.ORDER_BITWISE_XOR = 11;   // ^
Blockly.Java.ORDER_BITWISE_OR = 12;    // |
Blockly.Java.ORDER_LOGICAL_AND = 13;   // &&
Blockly.Java.ORDER_LOGICAL_OR = 14;    // ||
Blockly.Java.ORDER_CONDITIONAL = 15;   // ?:
Blockly.Java.ORDER_ASSIGNMENT = 16;    // = += -= *= /= %= <<= >>= ...
Blockly.Java.ORDER_COMMA = 17;         // ,
Blockly.Java.ORDER_NONE = 99;          // (...)

/**
 * Arbitrary code to inject into locations that risk causing infinite loops.
 * Any instances of '%1' will be replaced by the block ID that failed.
 * E.g. '  checkTimeout(%1);\n'
 * @type ?string
 */
Blockly.Java.INFINITE_LOOP_TRAP = null;

/**
 * Initialise the database of variable names.
 */
Blockly.Java.init = function() {
  //A set of all the import statments
  Blockly.Java.imports = [];
  // Create a dictionary of definitions to be printed before the code.
  Blockly.Java.definitions_ = Object.create(null);
  // Create a dictionary mapping desired function names in definitions_
  // to actual function names (to avoid collisions with user functions).
  Blockly.Java.functionNames_ = Object.create(null);

  if (Blockly.Variables) {
    if (!Blockly.Java.variableDB_) {
      Blockly.Java.variableDB_ =
          new Blockly.Names(Blockly.Java.RESERVED_WORDS_);
    } else {
      Blockly.Java.variableDB_.reset();
    }

    var defvars = [];
    var variables = Blockly.Variables.allVariables();
    for (var x = 0; x < variables.length; x++) {
      defvars[x] = 'var ' +
          Blockly.Java.variableDB_.getName(variables[x],
          Blockly.Variables.NAME_TYPE) + ';';
    }
    Blockly.Java.definitions_['variables'] = defvars.join('\n');
    // Blockly.Java.definitions_['imports'] = [];
  }
};

/**
 * Prepend the generated code with the variable definitions.
 * @param {string} code Generated code.
 * @return {string} Completed code.
 */
Blockly.Java.finish = function(code) {
  // Convert the definitions dictionary into a list.
  var definitions = [];
  for (var name in Blockly.Java.definitions_) {
    definitions = definitions.concat(Blockly.Java.definitions_[name]);
  }
  return definitions.join('\n') + '\n\n' + code;
};

/**
 * Naked values are top-level blocks with outputs that aren't plugged into
 * anything.  A trailing semicolon is needed to make this legal.
 * @param {string} line Line of generated code.
 * @return {string} Legal line of code.
 */
Blockly.Java.scrubNakedValue = function(line) {
  return line + ';\n';
};

/**
 * @todo Update for Java
 * Encode a string as a properly escaped JavaScript string, complete with
 * quotes.
 * @param {string} string Text to encode.
 * @return {string} Java string.
 * @private
 */
Blockly.Java.quote_ = function(string) {
  // TODO: This is a quick hack.  Replace with goog.string.quote
  string = string.replace(/\\/g, '\\\\')
                 .replace(/\n/g, '\\\n')
                 .replace(/'/g, '\\\'');
  return '\"' + string + '\"';
};

/**
 * Common tasks for generating Java from blocks.
 * Handles comments for the specified block and any connected value blocks.
 * Calls any statements following this block.
 * @param {!Blockly.Block} block The current block.
 * @param {string} code The Java code created for this block.
 * @return {string} Java code with comments and subsequent blocks added.
 * @private
 */
Blockly.Java.scrub_ = function(block, code) {
  if (code === null) {
    // Block has handled code generation itself.
    return '';
  }
  var commentCode = '';
  // Only collect comments for blocks that aren't inline.
  if (!block.outputConnection || !block.outputConnection.targetConnection) {
    // Collect comment for this block.
    var comment = block.getCommentText();
    if (comment) {
      commentCode += this.prefixLines(comment, '// ') + '\n';
    }
    // Collect comments for all value arguments.
    // Don't collect comments for nested statements.
    for (var x = 0; x < block.inputList.length; x++) {
      if (block.inputList[x].type == Blockly.INPUT_VALUE) {
        var childBlock = block.inputList[x].connection.targetBlock();
        if (childBlock) {
          var comment = this.allNestedComments(childBlock);
          if (comment) {
            commentCode += this.prefixLines(comment, '// ');
          }
        }
      }
    }
  }
  var nextBlock = block.nextConnection && block.nextConnection.targetBlock();
  var nextCode = this.blockToCode(nextBlock);
  return commentCode + code + nextCode;
};

Blockly.Java.addImport = function(imprt) {
  if ( !(Blockly.Java.imports.indexOf(imprt) > -1) ) //This will make it a set
    Blockly.Java.imports.push(imprt);
}

Blockly.Java.getImports = function() {
  return Blockly.Java.imports;
}

// This seems like a bit of a hack... but ohwells
Blockly.Java.workspaceToCode = function(rootBlk) {
  var code = [];
  this.init();
  var blocks = [];
  if (rootBlk) {
    blocks = [rootBlk];
  } else {
    blocks = Blockly.mainWorkspace.getTopBlocks(true);
  }
  for (var x = 0, block; block = blocks[x]; x++) {
    var line = this.blockToCode(block);
    if (goog.isArray(line)) {
      // Value blocks return tuples of code and operator order.
      // Top-level blocks don't care about operator order.
      line = line[0];
    }
    if (line) {
      if (block.outputConnection && this.scrubNakedValue) {
        // This block is a naked value.  Ask the language's code generator if
        // it wants to append a semicolon, or something.
        line = this.scrubNakedValue(line);
      }
      code.push(line);
    }
  }
  code = code.join('\n');  // Blank line between each section.
  code = this.finish(code);
  // Final scrubbing of whitespace.
  code = code.replace(/^\s+\n/, '');
  code = code.replace(/\n\s+$/, '\n');
  code = code.replace(/[ \t]+\n/g, '\n');
  return code;
};<commit_msg>add primitive types as recerved words<commit_after>/**
 * @license
 * Visual Blocks Language
 *
 * Copyright 2012 Google Inc.
 * https://blockly.googlecode.com/
 *
 * 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.
 */

/**
 * @fileoverview Helper functions for generating JavaScript for blocks.
 * @author fraser@google.com (Neil Fraser)
 */
'use strict';

goog.provide('Blockly.Java');

goog.require('Blockly.Generator');

Blockly.Java = new Blockly.Generator('Java');

/**
 * List of illegal variable names.
 * This is not intended to be a security feature.  Blockly is 100% client-side,
 * so bypassing this list is trivial.  This is intended to prevent users from
 * accidentally clobbering a built-in object or function.
 * @private
 */
Blockly.Java.addReservedWords(
  //http://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html
  'abstract,continue,for,new,switch,assert,default,goto,package,synchronized' +
  'boolean,do,if,private,this,break,double,implements,protected,throw,byte,else'+
  'import,public,throws,case,enum,instanceof,return,transient,catch,extends,int'+
  'short,try,char,final,interface,static,void,class,finally,long,strictfp'+
  'volatile,const,float,native,super,while'+
  'byte,short,int,long,float,double,boolean,char,String,string'
);

/**
 * Order of operation ENUMs.
 * https://developer.mozilla.org/en/JavaScript/Reference/Operators/Operator_Precedence
 * @todo Update for Java
 */
Blockly.Java.ORDER_ATOMIC = 0;         // 0 "" ...
Blockly.Java.ORDER_MEMBER = 1;         // . []
Blockly.Java.ORDER_NEW = 1;            // new
Blockly.Java.ORDER_FUNCTION_CALL = 2;  // ()
Blockly.Java.ORDER_INCREMENT = 3;      // ++
Blockly.Java.ORDER_DECREMENT = 3;      // --
Blockly.Java.ORDER_LOGICAL_NOT = 4;    // !
Blockly.Java.ORDER_BITWISE_NOT = 4;    // ~
Blockly.Java.ORDER_UNARY_PLUS = 4;     // +
Blockly.Java.ORDER_UNARY_NEGATION = 4; // -
Blockly.Java.ORDER_TYPEOF = 4;         // typeof
Blockly.Java.ORDER_VOID = 4;           // void
Blockly.Java.ORDER_DELETE = 4;         // delete
Blockly.Java.ORDER_MULTIPLICATION = 5; // *
Blockly.Java.ORDER_DIVISION = 5;       // /
Blockly.Java.ORDER_MODULUS = 5;        // %
Blockly.Java.ORDER_ADDITION = 6;       // +
Blockly.Java.ORDER_SUBTRACTION = 6;    // -
Blockly.Java.ORDER_BITWISE_SHIFT = 7;  // << >> >>>
Blockly.Java.ORDER_RELATIONAL = 8;     // < <= > >=
Blockly.Java.ORDER_IN = 8;             // in
Blockly.Java.ORDER_INSTANCEOF = 8;     // instanceof
Blockly.Java.ORDER_EQUALITY = 9;       // == != === !==
Blockly.Java.ORDER_BITWISE_AND = 10;   // &
Blockly.Java.ORDER_BITWISE_XOR = 11;   // ^
Blockly.Java.ORDER_BITWISE_OR = 12;    // |
Blockly.Java.ORDER_LOGICAL_AND = 13;   // &&
Blockly.Java.ORDER_LOGICAL_OR = 14;    // ||
Blockly.Java.ORDER_CONDITIONAL = 15;   // ?:
Blockly.Java.ORDER_ASSIGNMENT = 16;    // = += -= *= /= %= <<= >>= ...
Blockly.Java.ORDER_COMMA = 17;         // ,
Blockly.Java.ORDER_NONE = 99;          // (...)

/**
 * Arbitrary code to inject into locations that risk causing infinite loops.
 * Any instances of '%1' will be replaced by the block ID that failed.
 * E.g. '  checkTimeout(%1);\n'
 * @type ?string
 */
Blockly.Java.INFINITE_LOOP_TRAP = null;

/**
 * Initialise the database of variable names.
 */
Blockly.Java.init = function() {
  //A set of all the import statments
  Blockly.Java.imports = [];
  // Create a dictionary of definitions to be printed before the code.
  Blockly.Java.definitions_ = Object.create(null);
  // Create a dictionary mapping desired function names in definitions_
  // to actual function names (to avoid collisions with user functions).
  Blockly.Java.functionNames_ = Object.create(null);

  if (Blockly.Variables) {
    if (!Blockly.Java.variableDB_) {
      Blockly.Java.variableDB_ =
          new Blockly.Names(Blockly.Java.RESERVED_WORDS_);
    } else {
      Blockly.Java.variableDB_.reset();
    }

    var defvars = [];
    var variables = Blockly.Variables.allVariables();
    for (var x = 0; x < variables.length; x++) {
      defvars[x] = 'var ' +
          Blockly.Java.variableDB_.getName(variables[x],
          Blockly.Variables.NAME_TYPE) + ';';
    }
    Blockly.Java.definitions_['variables'] = defvars.join('\n');
    // Blockly.Java.definitions_['imports'] = [];
  }
};

/**
 * Prepend the generated code with the variable definitions.
 * @param {string} code Generated code.
 * @return {string} Completed code.
 */
Blockly.Java.finish = function(code) {
  // Convert the definitions dictionary into a list.
  var definitions = [];
  for (var name in Blockly.Java.definitions_) {
    definitions = definitions.concat(Blockly.Java.definitions_[name]);
  }
  return definitions.join('\n') + '\n\n' + code;
};

/**
 * Naked values are top-level blocks with outputs that aren't plugged into
 * anything.  A trailing semicolon is needed to make this legal.
 * @param {string} line Line of generated code.
 * @return {string} Legal line of code.
 */
Blockly.Java.scrubNakedValue = function(line) {
  return line + ';\n';
};

/**
 * @todo Update for Java
 * Encode a string as a properly escaped JavaScript string, complete with
 * quotes.
 * @param {string} string Text to encode.
 * @return {string} Java string.
 * @private
 */
Blockly.Java.quote_ = function(string) {
  // TODO: This is a quick hack.  Replace with goog.string.quote
  string = string.replace(/\\/g, '\\\\')
                 .replace(/\n/g, '\\\n')
                 .replace(/'/g, '\\\'');
  return '\"' + string + '\"';
};

/**
 * Common tasks for generating Java from blocks.
 * Handles comments for the specified block and any connected value blocks.
 * Calls any statements following this block.
 * @param {!Blockly.Block} block The current block.
 * @param {string} code The Java code created for this block.
 * @return {string} Java code with comments and subsequent blocks added.
 * @private
 */
Blockly.Java.scrub_ = function(block, code) {
  if (code === null) {
    // Block has handled code generation itself.
    return '';
  }
  var commentCode = '';
  // Only collect comments for blocks that aren't inline.
  if (!block.outputConnection || !block.outputConnection.targetConnection) {
    // Collect comment for this block.
    var comment = block.getCommentText();
    if (comment) {
      commentCode += this.prefixLines(comment, '// ') + '\n';
    }
    // Collect comments for all value arguments.
    // Don't collect comments for nested statements.
    for (var x = 0; x < block.inputList.length; x++) {
      if (block.inputList[x].type == Blockly.INPUT_VALUE) {
        var childBlock = block.inputList[x].connection.targetBlock();
        if (childBlock) {
          var comment = this.allNestedComments(childBlock);
          if (comment) {
            commentCode += this.prefixLines(comment, '// ');
          }
        }
      }
    }
  }
  var nextBlock = block.nextConnection && block.nextConnection.targetBlock();
  var nextCode = this.blockToCode(nextBlock);
  return commentCode + code + nextCode;
};

Blockly.Java.addImport = function(imprt) {
  if ( !(Blockly.Java.imports.indexOf(imprt) > -1) ) //This will make it a set
    Blockly.Java.imports.push(imprt);
}

Blockly.Java.getImports = function() {
  return Blockly.Java.imports;
}

// This seems like a bit of a hack... but ohwells
Blockly.Java.workspaceToCode = function(rootBlk) {
  var code = [];
  this.init();
  var blocks = [];
  if (rootBlk) {
    blocks = [rootBlk];
  } else {
    blocks = Blockly.mainWorkspace.getTopBlocks(true);
  }
  for (var x = 0, block; block = blocks[x]; x++) {
    var line = this.blockToCode(block);
    if (goog.isArray(line)) {
      // Value blocks return tuples of code and operator order.
      // Top-level blocks don't care about operator order.
      line = line[0];
    }
    if (line) {
      if (block.outputConnection && this.scrubNakedValue) {
        // This block is a naked value.  Ask the language's code generator if
        // it wants to append a semicolon, or something.
        line = this.scrubNakedValue(line);
      }
      code.push(line);
    }
  }
  code = code.join('\n');  // Blank line between each section.
  code = this.finish(code);
  // Final scrubbing of whitespace.
  code = code.replace(/^\s+\n/, '');
  code = code.replace(/\n\s+$/, '\n');
  code = code.replace(/[ \t]+\n/g, '\n');
  return code;
};<|endoftext|>


<commit_before>
/**
    Pathway Commons Central Data Cache

    Database Server Query Routing
    databaseRoutes.js

    Purpose : Provides functions to read from and write to the database.

    Requires : None

    Effects : None

    Note : None

    TODO:
    - ensure querying via socket.io still works
    - Run proper functionality testing

    @author Geoff Elder
    @version 1.1 2017/10/10
**/

//Import Depedencies
const auth = require('./auth.js');
const accessDB = require('./../database/accessDB.js')('testLayouts');
const saveDiffs = require('./../database/saveDiffs')('testLayouts');
const lazyLoad = require('./../lazyload');
const btoa = require('btoa');

const express = require('express');
const router = express.Router();

var connPromise = accessDB.connect(); // returns a promise.

var returnRouter = function () {

  // ------------------ Standard API Functions (Sans Socket IO) ----------------
  //Get Layout
  router.get('/Get', function (req, res) {
    //Get the requested layout
    try {
      connPromise.then((connection) => {
        var graph = accessDB.getGraph(
          req.query.uri,
          req.query.version,
          connection
        );
        var layout = accessDB.getLayout(
          req.query.uri,
          req.query.version,
          connection
        );

        return Promise.all([graph, layout]);
      }).catch((e) => {
        throw e;
      }).then(([graph, layout]) => {
        // Optimal case - everything works.
        if (graph && layout) {
          res.json({ graph: graph.graph, layout: layout.positions });
          // Graph exists but layout not found. Return null to tell front end to a default load precomputed layout
        } else if (graph) {
          res.json({ graph: graph.graph, layout: null });
          // Layout exists without a graph. This should be truly impossible and should throw an error.
        } else if (layout) {
          throw new Error('Error: Case not handled. But this really shouldn\'t happen');
          // No graph or layout. Lazy load everything from pathway commons
        } else {
          lazyLoad.queryPC(req.query.uri, req.query.version).then((result) => {
            if (result) {
              res.json({ graph: result, layout: null });

            } else {
              res.json(null);
            }
          });
        }

      }).catch((e) => {
        res.json(e);
        //throw e;
      });
    } catch (e) {
      res.json('ERROR : Layout Request Failed!');
    }
  });

  router.get('/getEditKey', function (req, res) {

    try {
      connPromise.then((connection) => {
        if (auth.checkUser(req)) {
          accessDB.getGraphID(
            req.query.uri,
            req.query.version,
            connection,
            function (result) {
              if (result) {
                res.json(result);
              } else {
                res.json('ERROR: No edit key could be found');
              }
            });
        } else {
          res.json('ERROR: Non-authenticated user');
        }
      }).catch((e) => {
        res.json('ERROR: Edit Key Request Failed');
      });
    }
    catch (e) {
      res.json('ERROR: Edit Key Request Failed');
    }
  });

  router.get('/checkEditKey', function (req, res) {
    if (!(req.query.uri && req.query.version)) {
      res.json('ERROR: Required Parameters Not Defined');
      return;
    }

    try {
      connPromise.then((connection) => {
        accessDB.getGraphID(
          req.query.uri,
          req.query.version,
          connection,
          function (result) { res.json(result === req.query.key); }
        );
      }).catch((err) => {
        res.json('ERROR : Edit Priviliges Check Failed');
      });
    } catch (e) {
      res.json('ERROR : Edit Priviliges Check Failed');
    }

  });

  router.post('/Submit', function (req, res) {
    if (!(req.body.layout && req.body.version && req.body.uri)) {
      res.json = ('ERROR : Required Parameters Undefined');
      return;
    }
    //Get the requested layout
    try {
      connPromise.then((connection) => {
        if (auth.checkUser(req)) {
          accessDB.saveLayout(req.body.uri,
            req.body.layout,
            req.body.version,
            connection,
            function () { res.json('Success: Update Applied!'); });
        }
        else {
          res.json('ERROR : You Do Not Have Valid Permissions!');
        }
      }).catch((e) => {
        res.json('ERROR: Layout Update Failed!');
      });
    }
    catch (e) {
      res.json('ERROR : Layout Update Failed!');
      throw e;
    }
  });

  //Return Confirmation
  router.get('/', function (req, res) {
    res.json('This Server Uses Socket.io!');
  });

  return router;
};

module.exports = returnRouter;<commit_msg>Updated route names.<commit_after>
/**
    Pathway Commons Central Data Cache

    Database Server Query Routing
    databaseRoutes.js

    Purpose : Provides functions to read from and write to the database.

    Requires : None

    Effects : None

    Note : None

    TODO:
    - ensure querying via socket.io still works
    - Run proper functionality testing

    @author Geoff Elder
    @version 1.1 2017/10/10
**/

//Import Depedencies
const auth = require('./auth.js');
const accessDB = require('./../database/accessDB.js')('testLayouts');
const saveDiffs = require('./../database/saveDiffs')('testLayouts');
const lazyLoad = require('./../lazyload');
const btoa = require('btoa');

const express = require('express');
const router = express.Router();

var connPromise = accessDB.connect(); // returns a promise.

var returnRouter = function () {

  // ------------------ Standard API Functions (Sans Socket IO) ----------------
  //Get Layout
  router.get('/get', function (req, res) {
    //Get the requested layout
    try {
      connPromise.then((connection) => {
        var graph = accessDB.getGraph(
          req.query.uri,
          req.query.version,
          connection
        );
        var layout = accessDB.getLayout(
          req.query.uri,
          req.query.version,
          connection
        );

        return Promise.all([graph, layout]);
      }).catch((e) => {
        throw e;
      }).then(([graph, layout]) => {
        // Optimal case - everything works.
        if (graph && layout) {
          res.json({ graph: graph.graph, layout: layout.positions });
          // Graph exists but layout not found. Return null to tell front end to a default load precomputed layout
        } else if (graph) {
          res.json({ graph: graph.graph, layout: null });
          // Layout exists without a graph. This should be truly impossible and should throw an error.
        } else if (layout) {
          throw new Error('Error: Case not handled. But this really shouldn\'t happen');
          // No graph or layout. Lazy load everything from pathway commons
        } else {
          lazyLoad.queryPC(req.query.uri, req.query.version).then((result) => {
            if (result) {
              res.json({ graph: result, layout: null });

            } else {
              res.json(null);
            }
          });
        }

      }).catch((e) => {
        res.json(e);
        //throw e;
      });
    } catch (e) {
      res.json('ERROR : Layout Request Failed!');
    }
  });

  router.get('/get-edit-key', function (req, res) {

    try {
      connPromise.then((connection) => {
        if (auth.checkUser(req)) {
          accessDB.getGraphID(
            req.query.uri,
            req.query.version,
            connection,
            function (result) {
              if (result) {
                res.json(result);
              } else {
                res.json('ERROR: No edit key could be found');
              }
            });
        } else {
          res.json('ERROR: Non-authenticated user');
        }
      }).catch((e) => {
        res.json('ERROR: Edit Key Request Failed');
      });
    }
    catch (e) {
      res.json('ERROR: Edit Key Request Failed');
    }
  });

  router.get('/check-edit-key', function (req, res) {
    if (!(req.query.uri && req.query.version)) {
      res.json('ERROR: Required Parameters Not Defined');
      return;
    }

    try {
      connPromise.then((connection) => {
        accessDB.getGraphID(
          req.query.uri,
          req.query.version,
          connection,
          function (result) { res.json(result === req.query.key); }
        );
      }).catch((err) => {
        res.json('ERROR : Edit Priviliges Check Failed');
      });
    } catch (e) {
      res.json('ERROR : Edit Priviliges Check Failed');
    }

  });

  router.post('/submit', function (req, res) {
    if (!(req.body.layout && req.body.version && req.body.uri)) {
      res.json = ('ERROR : Required Parameters Undefined');
      return;
    }
    //Get the requested layout
    try {
      connPromise.then((connection) => {
        if (auth.checkUser(req)) {
          accessDB.saveLayout(req.body.uri,
            req.body.layout,
            req.body.version,
            connection,
            function () { res.json('Success: Update Applied!'); });
        }
        else {
          res.json('ERROR : You Do Not Have Valid Permissions!');
        }
      }).catch((e) => {
        res.json('ERROR: Layout Update Failed!');
      });
    }
    catch (e) {
      res.json('ERROR : Layout Update Failed!');
      throw e;
    }
  });

  //Return Confirmation
  router.get('/', function (req, res) {
    res.json('This Server Uses Socket.io!');
  });

  return router;
};

module.exports = returnRouter;<|endoftext|>


<commit_before>/*
 * This file is part of Cockpit.
 *
 * Copyright (C) 2015 Red Hat, Inc.
 *
 * Cockpit is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * Cockpit is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
 */

(function(root, factory) {
    if (typeof(define) === 'function' && define.amd)
        define(["./angular", "./d3" ], factory);
    else
        factory(root.angular, root.d3);
}(this, function(angular, d3) {
    "use strict";

    function topology_graph(selector, notify) {
        var outer = d3.select(selector);

        /* Kinds of objects to show */
        var kinds = null;

        /* Data we've been fed */
        var items = { };
        var relations = [ ];

        /* Cached information */
        var width;
        var height;
        var timeout;
        var nodes = [];
        var links = [];
        var lookup = { };

        var force = d3.layout.force()
            .charge(-800)
            .gravity(0.2)
            .linkDistance(80);

        var drag = force.drag();

        var svg = outer.append("svg").attr("class", "kube-topology");

        var vertices = d3.select();
        var edges = d3.select();

        force.on("tick", function() {
            edges.attr("x1", function(d) { return d.source.x; })
                 .attr("y1", function(d) { return d.source.y; })
                 .attr("x2", function(d) { return d.target.x; })
                 .attr("y2", function(d) { return d.target.y; });

            vertices.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
        });

        drag
            .on("dragstart", function(d) {
                notify(d.item);
                svg.selectAll("g").classed("selected", false);
                d3.select(this).classed("selected", true);

                if (d.fixed !== true)
                    d.floatpoint = [ d.x, d.y ];
                d.fixed = true;
                d3.select(this).classed("fixed", true);
            })
            .on("dragend", function(d) {
                var moved = true;
                if (d.floatpoint) {
                    moved = (d.x < d.floatpoint[0] - 5 || d.x > d.floatpoint[0] + 5) ||
                            (d.y < d.floatpoint[1] - 5 || d.y > d.floatpoint[1] + 5);
                    delete d.floatpoint;
                }
                d.fixed = moved && d.x > 3 && d.x < (width - 3) && d.y >= 3 && d.y < (height - 3);
                d3.select(this).classed("fixed", d.fixed);
            });

        svg
            .on("dblclick", function() {
                svg.selectAll("g")
                    .classed("fixed", false)
                    .each(function(d) { d.fixed = false; });
                force.start();
            })
            .on("click", function(ev) {
                if (!d3.select(d3.event.target).datum()) {
                    notify(null);
                    svg.selectAll("g").classed("selected", false);
                }
            });

        function icon(d) {
	    var text;
	    if (kinds)
		text = kinds[d.item.kind];
	    return text || "";
	}

        function weak(d) {
	    var status = d.item.status;
            if (status && status.phase && status.phase !== "Running")
                return true;
            return false;
        }

        function adjust() {
            timeout = null;
            width = outer.node().clientWidth;
            height = outer.node().clientHeight;

            force.size([width, height]);
            svg.attr("width", width).attr("height", height);
            update();
        }

        function update() {
            edges = svg.selectAll("line")
                .data(links);

            edges.exit().remove();
            edges.enter().insert("line", ":first-child");

            edges.attr("class", function(d) { return d.kinds; });

            vertices = svg.selectAll("g")
                .data(nodes, function(d) { return d.id; })
                .classed("weak", weak);

            vertices.exit().remove();

            var group = vertices.enter().append("g")
                .attr("class", function(d) { return d.item.kind; })
                .classed("weak", weak)
                .call(drag);

            group.append("use")
                .attr("xlink:href", icon);
            group.append("title")
                .text(function(d) { return d.item.metadata.name; });

            force
                .nodes(nodes)
                .links(links)
                .start();
        }

        function digest() {
            var pnodes = nodes;
            var plookup = lookup;

            /* The actual data for the graph */
            nodes = [];
            links = [];
            lookup = { };

            var item, id, kind, node;
            for (id in items) {
                item = items[id];
                kind = item.kind;

                if (kinds && !kinds[kind])
                    continue;

                /* Prevents flicker */
                node = pnodes[plookup[id]];
                if (!node)
	            node = { y: height / 2, x: width / 2, py: height / 2, px: width / 2 };
                node.id = id;
                node.item = item;

                lookup[id] = nodes.length;
                nodes.push(node);
            }

            var i, len, relation, s, t;
            for (i = 0, len = relations.length; i < len; i++) {
                relation = relations[i];

                s = lookup[relation.source];
                t = lookup[relation.target];
                if (s === undefined || t === undefined)
                    continue;

                links.push({ source: s, target: t, kinds: nodes[s].item.kind + nodes[t].item.kind });
            }

            update();
        }

        function resized() {
            if (!timeout)
                timeout = window.setTimeout(adjust, 50);
        }

        window.addEventListener('resize', resized);
        resized();

        return {
            kinds: function(value) {
                if (arguments.length === 0)
                    return kinds;
                kinds = value;
                digest();
            },
	    data: function(new_items, new_relations) {
                if (arguments.length === 0)
                    return [items, relations];
                items = new_items || { };
                relations = new_relations || [];
                digest();
            },
            close: function() {
	        window.removeEventListener('resize', resized);
                window.clearTimeout(timeout);
            }
        };
    }

    /* The kubernetesUI component is quite loosely bound, define if it doesn't exist */
    try { angular.module("kubernetesUI"); } catch(e) { angular.module("kubernetesUI", []); }

    return angular.module('kubernetesUI')
        .directive('kubernetesTopologyGraph', [
            function() {
                return {
                    restrict: 'E',
                    scope: {
                        items: '=',
                        relations: '=',
                        kinds: '='
                    },
                    link: function($scope, element, attributes) {
                        element.css("display", "block");

                        function notify(item) {
                            $scope.$emit("selected", item);
                        }

                        var graph = topology_graph(element[0], notify);
                        graph.kinds($scope.kinds);

                        /* If there's a kinds in the current scope, watch it for changes */
                        $scope.$watchCollection("kinds", function(value) {
                            graph.kinds(value);
                        });

                        $scope.$watchGroup(["items", "relations"], function(values) {
                            graph.data(values[0], values[1]);
                        });

                        element.on("$destroy", function() {
                            graph.close();
                        });
                    }
                };
            }
        ])

        .directive('kubernetesTopologyIcon',
            function() {
                return {
                    restrict: 'E',
	            transclude: true,
                    template: "<ng-transclude></ng-transclude>",
                    link: function($scope, element, attrs) {
                        var kind = attrs.kind;
                        var icon = $scope.kinds[kind];

                        $scope.$watchCollection("kinds", function() {
                            element.toggleClass("active", kind in $scope.kinds);
                        });

                        element.on("click", function() {
                            if (kind in $scope.kinds) {
	                        icon = $scope.kinds[kind];
                                delete $scope.kinds[kind];
                            } else {
                                $scope.kinds[kind] = icon;
                            }
                            if ($scope.$parent)
	                        $scope.$parent.$digest();
	                    $scope.$digest();
                        });
                    }
                };
            }
        );
}));
<commit_msg>Use svg viewBox to fill browser viewport more nicely<commit_after>/*
 * This file is part of Cockpit.
 *
 * Copyright (C) 2015 Red Hat, Inc.
 *
 * Cockpit is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * Cockpit is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
 */

(function(root, factory) {
    if (typeof(define) === 'function' && define.amd)
        define(["./angular", "./d3" ], factory);
    else
        factory(root.angular, root.d3);
}(this, function(angular, d3) {
    "use strict";

    function topology_graph(selector, notify) {
        var outer = d3.select(selector);

        /* Kinds of objects to show */
        var kinds = null;

        /* Data we've been fed */
        var items = { };
        var relations = [ ];

        /* Cached information */
        var width;
        var height;
        var timeout;
        var nodes = [];
        var links = [];
        var lookup = { };

        var force = d3.layout.force()
            .charge(-800)
            .gravity(0.2)
            .linkDistance(80);

        var drag = force.drag();

        var svg = outer.append("svg")
            .attr("viewBox", "0 0 1600 1200")
            .attr("preserveAspectRatio", "xMidYMid meet")
            .attr("class", "kube-topology");

        var vertices = d3.select();
        var edges = d3.select();

        force.on("tick", function() {
            edges.attr("x1", function(d) { return d.source.x; })
                 .attr("y1", function(d) { return d.source.y; })
                 .attr("x2", function(d) { return d.target.x; })
                 .attr("y2", function(d) { return d.target.y; });

            vertices.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
        });

        drag
            .on("dragstart", function(d) {
                notify(d.item);
                svg.selectAll("g").classed("selected", false);
                d3.select(this).classed("selected", true);

                if (d.fixed !== true)
                    d.floatpoint = [ d.x, d.y ];
                d.fixed = true;
                d3.select(this).classed("fixed", true);
            })
            .on("dragend", function(d) {
                var moved = true;
                if (d.floatpoint) {
                    moved = (d.x < d.floatpoint[0] - 5 || d.x > d.floatpoint[0] + 5) ||
                            (d.y < d.floatpoint[1] - 5 || d.y > d.floatpoint[1] + 5);
                    delete d.floatpoint;
                }
                d.fixed = moved && d.x > 3 && d.x < (width - 3) && d.y >= 3 && d.y < (height - 3);
                d3.select(this).classed("fixed", d.fixed);
            });

        svg
            .on("dblclick", function() {
                svg.selectAll("g")
                    .classed("fixed", false)
                    .each(function(d) { d.fixed = false; });
                force.start();
            })
            .on("click", function(ev) {
                if (!d3.select(d3.event.target).datum()) {
                    notify(null);
                    svg.selectAll("g").classed("selected", false);
                }
            });

        function icon(d) {
	    var text;
	    if (kinds)
		text = kinds[d.item.kind];
	    return text || "";
	}

        function weak(d) {
	    var status = d.item.status;
            if (status && status.phase && status.phase !== "Running")
                return true;
            return false;
        }

        function adjust() {
            timeout = null;
            width = outer.node().clientWidth;
            height = outer.node().clientHeight;

            force.size([width, height]);
            svg.attr("viewBox", "0 0 " + width + " " + height);
            update();
        }

        function update() {
            edges = svg.selectAll("line")
                .data(links);

            edges.exit().remove();
            edges.enter().insert("line", ":first-child");

            edges.attr("class", function(d) { return d.kinds; });

            vertices = svg.selectAll("g")
                .data(nodes, function(d) { return d.id; })
                .classed("weak", weak);

            vertices.exit().remove();

            var group = vertices.enter().append("g")
                .attr("class", function(d) { return d.item.kind; })
                .classed("weak", weak)
                .call(drag);

            group.append("use")
                .attr("xlink:href", icon);
            group.append("title")
                .text(function(d) { return d.item.metadata.name; });

            force
                .nodes(nodes)
                .links(links)
                .start();
        }

        function digest() {
            var pnodes = nodes;
            var plookup = lookup;

            /* The actual data for the graph */
            nodes = [];
            links = [];
            lookup = { };

            var item, id, kind, node;
            for (id in items) {
                item = items[id];
                kind = item.kind;

                if (kinds && !kinds[kind])
                    continue;

                /* Prevents flicker */
                node = pnodes[plookup[id]];
                if (!node)
	            node = { y: height / 2, x: width / 2, py: height / 2, px: width / 2 };
                node.id = id;
                node.item = item;

                lookup[id] = nodes.length;
                nodes.push(node);
            }

            var i, len, relation, s, t;
            for (i = 0, len = relations.length; i < len; i++) {
                relation = relations[i];

                s = lookup[relation.source];
                t = lookup[relation.target];
                if (s === undefined || t === undefined)
                    continue;

                links.push({ source: s, target: t, kinds: nodes[s].item.kind + nodes[t].item.kind });
            }

            update();
        }

        function resized() {
            if (!timeout)
                timeout = window.setTimeout(adjust, 50);
        }

        window.addEventListener('resize', resized);
        resized();

        return {
            kinds: function(value) {
                if (arguments.length === 0)
                    return kinds;
                kinds = value;
                digest();
            },
	    data: function(new_items, new_relations) {
                if (arguments.length === 0)
                    return [items, relations];
                items = new_items || { };
                relations = new_relations || [];
                digest();
            },
            close: function() {
	        window.removeEventListener('resize', resized);
                window.clearTimeout(timeout);
            }
        };
    }

    /* The kubernetesUI component is quite loosely bound, define if it doesn't exist */
    try { angular.module("kubernetesUI"); } catch(e) { angular.module("kubernetesUI", []); }

    return angular.module('kubernetesUI')
        .directive('kubernetesTopologyGraph', [
            function() {
                return {
                    restrict: 'E',
                    scope: {
                        items: '=',
                        relations: '=',
                        kinds: '='
                    },
                    link: function($scope, element, attributes) {
                        element.css("display", "block");

                        function notify(item) {
                            $scope.$emit("selected", item);
                        }

                        var graph = topology_graph(element[0], notify);
                        graph.kinds($scope.kinds);

                        /* If there's a kinds in the current scope, watch it for changes */
                        $scope.$watchCollection("kinds", function(value) {
                            graph.kinds(value);
                        });

                        $scope.$watchGroup(["items", "relations"], function(values) {
                            graph.data(values[0], values[1]);
                        });

                        element.on("$destroy", function() {
                            graph.close();
                        });
                    }
                };
            }
        ])

        .directive('kubernetesTopologyIcon',
            function() {
                return {
                    restrict: 'E',
	            transclude: true,
                    template: "<ng-transclude></ng-transclude>",
                    link: function($scope, element, attrs) {
                        var kind = attrs.kind;
                        var icon = $scope.kinds[kind];

                        $scope.$watchCollection("kinds", function() {
                            element.toggleClass("active", kind in $scope.kinds);
                        });

                        element.on("click", function() {
                            if (kind in $scope.kinds) {
	                        icon = $scope.kinds[kind];
                                delete $scope.kinds[kind];
                            } else {
                                $scope.kinds[kind] = icon;
                            }
                            if ($scope.$parent)
	                        $scope.$parent.$digest();
	                    $scope.$digest();
                        });
                    }
                };
            }
        );
}));
<|endoftext|>


<commit_before>var VERBOSE = true;

class Domain {
  constructor(options){
    this.domain = options.domain;
    this.template = null;
    this.productivity = options.productivity == undefined ? options.productivity : 0;
    this.visits = options.visits;
    this.history = {};
  }

  render(){
    var compiled = _.template(this.template);
    return compiled(this.toObject());
  }

  toObject(){
    var obj = {};
    obj.domain = this.domain;
    obj.productivity = this.productivity;
    return obj;
  }

  setTemplate(template){
    if(typeof template == "object"){ template = template.join("\n"); }
    this.template = template;
  }

  setHistory(historyObject){
  }

  isProductive(val){
    /* 0: UNKNOWN | 1: UNPRODUCTIVE | 2: PRODUCTIVE */
    if(val != undefined){ this.isProductive = val; }
    return this.isProductive;
  }
}

/**** TEST DUMMY DATA ****/
var exampleDomains = [
  {
    domain: "domain.com",
    visits: 58,
    lastSevenDays: null,
    productivity: 2,
  },
  {
    domain: "bomb.com",
    visits: 68,
    lastSevenDays: null,
    productivity: 1,
  },
  {
    domain: "wombo.com",
    visits: 20,
    lastSevenDays: null,
    productivity: 1
  },
  {
    domain: "everybodywombo.com",
    visits: 90,
    lastSevenDays: null,
    productivity: 0
  },
];

var domains = [];
for(var item of exampleDomains){
  var d = new Domain(item);
  domains.push(d);
}
//*/
/**** END TEST DUMMY DATA ****/

//var data = [{ val: 2, legend: "Productive" }, { val: 6, legend: "Unknown" }, { val: 4, legend: "Unproductive" }];

var renderGraph = function(domains) { ///recieve data to render and decide what to render
  if(VERBOSE){ console.debug("FUNCTION CALL: renderGraph()"); }
  var categoryData = [{x: "Unknown", visits: 0, value: 0}, {x: "Unproductive", visits: 0, value: 1}, {x: "Productive", visits: 0, value: 2}];
  for(item of domains){
    categoryData[item.productivity].visits += item.visits;
  }
  //renderPieGraph(categoryData);
  renderBarGraph(categoryData);
}

var renderBarGraph = function (data) {
  console.log(data);
  var colorScale = new Plottable.Scales.Color();
  colorScale.range(["#FF00FF", "#FF0000", "#0000FF"]);

  var xScale = new Plottable.Scales.Category();
  var yScale = new Plottable.Scales.Linear();

  var xAxis = new Plottable.Axes.Category(xScale, "bottom");
  var yAxis = new Plottable.Axes.Numeric(yScale, "left");

  var baseVal = (data[0].visits)/2;
  for(item of data){
    if((item.visits/2) < baseVal){
        baseVal = (item.visits/2);
    }
  }

  var plot = new Plottable.Plots.Bar()
    .addDataset(new Plottable.Dataset(data))
    .x(function(d) { return d.x; }, xScale)
    .y(function(d) { return d.visits; }, yScale)
    .animated(true)
    .attr("fill", function(d) { return d.visits; }, colorScale)
    .baselineValue(baseVal)
    .labelsEnabled(true);
  new Plottable.Components.Table([
    [yAxis,plot],
    [null,xAxis]
  ]).renderTo("svg#graph");
  window.addEventListener("resize", function() { plot.redraw(); });
}

var renderPieGraph = function (data) {
  var scale = new Plottable.Scales.Linear();
  var colorScale = new Plottable.Scales.InterpolatedColor();
  colorScale.range(["#BDCEF0", "#5279C7"]);
  var legend = new Plottable.Components.Legend(colorScale)
  colorScale.domain([data[0].visits,data[1].visits,data[2].visits]);
  console.log(colorScale.domain());
  legend.xAlignment("left")
  legend.yAlignment("top");

  var plot = new Plottable.Plots.Pie()
  .addDataset(new Plottable.Dataset(data))
  .sectorValue(function(d) { return d.visits; }, scale)
  .innerRadius(0)
  .attr("fill", function(d) { return d.visits; }, colorScale)
  .outerRadius(60)
  .renderTo("svg#graph");
  legend.renderTo("svg#graph")
  window.addEventListener("resize", function() { plot.redraw(); });
}

var fetchWikipediaArticle = function(titleName){

  var wikiArticleLink = "http://en.wikipedia.org/wiki/" + titleName;

  var container = $(".wikipedia-container");
  var templateString = wikipediaArticleTemplate.join("\n");
  var compiled = _.template(templateString);

  var handleData = function(data){

    var truncatedSummary = "not found";
    var imageUrl = "images/notfound.png";
    var title = "Article Could Not Be Fetched";

    if(data.summary != undefined){
      if(data.summary.title != undefined){
        title = data.summary.title;
      }

      if(data.summary.image != undefined){
        imageUrl = data.summary.image;
      }

      if(data.summary.summary != undefined){
        truncatedSummary = data.summary.summary.substring(0,150) + "...";
      }
    }

    var rendered = compiled({
      title: title,
      imageUrl: imageUrl,
      summary: truncatedSummary
    });

    container.append(rendered);
  }

  WIKIPEDIA.getData(wikiArticleLink, handleData);

  /****
  var wikiArticleLink = "http://en.wikipedia.org/wiki/Invasion_of_Normandy";
  var handleData = function(data){

    console.log(data.summary);
    console.log(data.summary.title);

    $("#title").html($("#title").html() + "" + data.summary.title);

    console.log(data.summary.summary);
    $("#summary").html($("#summary").html() + "" + data.summary.summary.substring(0,150) + "...");

    console.log(data.summary.image);
    //$("#image").html($("#image").html() + "" + data.summary.image);
    $("#put-image-here").attr("src", imageLink(data));
    $("#image-link").attr("href", wikiArticleLink);
  }

  function imageLink(data){
    return data.summary.image;
  }

  var handleError = function handleError(error){
    console.log(error);
  }

  */
}

var renderDomainList = function(domains, renderTargetSelector){
  if(VERBOSE){ console.debug("FUNCTION: renderDomainList()", domains, renderTargetSelector); }

  //Somewhere in here throws the error
  /*Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval'
    is not an allowed source of script in the following Content Security Policy directive:
    "script-src 'self' blob: filesystem: chrome-extension-resource:".*/

  var str = "";
  for(var d of domains){
    d.setTemplate(domainListingTemplate);
    str += d.render();
  }

  for(var n of $(renderTargetSelector)){
    n.innerHTML = str;
  }
}

var DOMLoaded = function() {
  if(VERBOSE){ console.debug("EVENT: DOMContentLoaded"); }
  console.log(getDomains());
  renderGraph(exampleDomains);
  renderDomainList(domains, "ul.domain-list-productive");
  var articles = ["Invasion_of_Normandy", "Banana", "Arthur_Tedder,_1st_Baron_Tedder"];
  for(var a of articles){
    fetchWikipediaArticle(a);
  }
}

document.addEventListener('DOMContentLoaded', DOMLoaded, false);
<commit_msg>added functional pieGraph w/ legend to browsing analytics<commit_after>var VERBOSE = true;

class Domain {
  constructor(options){
    this.domain = options.domain;
    this.template = null;
    this.productivity = options.productivity == undefined ? options.productivity : 0;
    this.visits = options.visits;
    this.history = {};
  }

  render(){
    var compiled = _.template(this.template);
    return compiled(this.toObject());
  }

  toObject(){
    var obj = {};
    obj.domain = this.domain;
    obj.productivity = this.productivity;
    return obj;
  }

  setTemplate(template){
    if(typeof template == "object"){ template = template.join("\n"); }
    this.template = template;
  }

  setHistory(historyObject){
  }

  isProductive(val){
    /* 0: UNKNOWN | 1: UNPRODUCTIVE | 2: PRODUCTIVE */
    if(val != undefined){ this.isProductive = val; }
    return this.isProductive;
  }
}

/**** TEST DUMMY DATA ****/
var exampleDomains = [
  {
    domain: "domain.com",
    visits: 58,
    lastSevenDays: null,
    productivity: 2,
  },
  {
    domain: "bomb.com",
    visits: 68,
    lastSevenDays: null,
    productivity: 1,
  },
  {
    domain: "wombo.com",
    visits: 20,
    lastSevenDays: null,
    productivity: 1
  },
  {
    domain: "everybodywombo.com",
    visits: 90,
    lastSevenDays: null,
    productivity: 0
  },
];

var domains = [];
for(var item of exampleDomains){
  var d = new Domain(item);
  domains.push(d);
}
//*/
/**** END TEST DUMMY DATA ****/

/*
*   recieve data to render and decide what to render
*   renderGraph manages and decides which graph to render
*   based on input
*/
var renderGraph = function(domains) {
  if(VERBOSE){ console.debug("FUNCTION CALL: renderGraph()"); }
  var categoryData = [{x: "Unknown", visits: 0, value: 0}, {x: "Unproductive", visits: 0, value: 1}, {x: "Productive", visits: 0, value: 2}];
  for(item of domains){
    categoryData[item.productivity].visits += item.visits;
  }
  renderPieGraph(categoryData);
  //renderBarGraph(categoryData);
}

var renderBarGraph = function (data) {
  console.log(data);
  var colorScale = new Plottable.Scales.Color();
  colorScale.range(["#FF00FF", "#FF0000", "#0000FF"]);

  var xScale = new Plottable.Scales.Category();
  var yScale = new Plottable.Scales.Linear();

  var xAxis = new Plottable.Axes.Category(xScale, "bottom");
  var yAxis = new Plottable.Axes.Numeric(yScale, "left");

  var baseVal = (data[0].visits)/2;
  for(item of data){
    if((item.visits/2) < baseVal){
        baseVal = (item.visits/2);
    }
  }

  var plot = new Plottable.Plots.Bar()
    .addDataset(new Plottable.Dataset(data))
    .x(function(d) { return d.x; }, xScale)
    .y(function(d) { return d.visits; }, yScale)
    .animated(true)
    .attr("fill", function(d) { return d.visits; }, colorScale)
    .baselineValue(baseVal)
    .labelsEnabled(true);
  new Plottable.Components.Table([
    [yAxis,plot],
    [null,xAxis]
  ]).renderTo("svg#graph");
  window.addEventListener("resize", function() { plot.redraw(); });
}

var renderPieGraph = function (data) {
  var scale = new Plottable.Scales.Linear();
  var colorScale = new Plottable.Scales.Color();
  colorScale.range(["#FF00FF", "#FF0000", "#0000FF"]);
  var legend = new Plottable.Components.Legend(colorScale)
  colorScale.domain([data[0].x,data[1].x,data[2].x]);
  legend.xAlignment("left")
  legend.yAlignment("top");

  var plot = new Plottable.Plots.Pie()
  .addDataset(new Plottable.Dataset(data))
  .sectorValue(function(d) { return d.visits; }, scale)
  .innerRadius(0)
  .attr("fill", function(d) { return d.x; }, colorScale)
  .outerRadius(60)
  .labelsEnabled(true)
  .renderTo("svg#graph");
  legend.renderTo("svg#graph")
  window.addEventListener("resize", function() { plot.redraw(); });
}

var fetchWikipediaArticle = function(titleName){

  var wikiArticleLink = "http://en.wikipedia.org/wiki/" + titleName;

  var container = $(".wikipedia-container");
  var templateString = wikipediaArticleTemplate.join("\n");
  var compiled = _.template(templateString);

  var handleData = function(data){

    var truncatedSummary = "not found";
    var imageUrl = "images/notfound.png";
    var title = "Article Could Not Be Fetched";

    if(data.summary != undefined){
      if(data.summary.title != undefined){
        title = data.summary.title;
      }

      if(data.summary.image != undefined){
        imageUrl = data.summary.image;
      }

      if(data.summary.summary != undefined){
        truncatedSummary = data.summary.summary.substring(0,150) + "...";
      }
    }

    var rendered = compiled({
      title: title,
      imageUrl: imageUrl,
      summary: truncatedSummary
    });

    container.append(rendered);
  }

  WIKIPEDIA.getData(wikiArticleLink, handleData);

  /****
  var wikiArticleLink = "http://en.wikipedia.org/wiki/Invasion_of_Normandy";
  var handleData = function(data){

    console.log(data.summary);
    console.log(data.summary.title);

    $("#title").html($("#title").html() + "" + data.summary.title);

    console.log(data.summary.summary);
    $("#summary").html($("#summary").html() + "" + data.summary.summary.substring(0,150) + "...");

    console.log(data.summary.image);
    //$("#image").html($("#image").html() + "" + data.summary.image);
    $("#put-image-here").attr("src", imageLink(data));
    $("#image-link").attr("href", wikiArticleLink);
  }

  function imageLink(data){
    return data.summary.image;
  }

  var handleError = function handleError(error){
    console.log(error);
  }

  */
}

var renderDomainList = function(domains, renderTargetSelector){
  if(VERBOSE){ console.debug("FUNCTION: renderDomainList()", domains, renderTargetSelector); }

  //Somewhere in here throws the error
  /*Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval'
    is not an allowed source of script in the following Content Security Policy directive:
    "script-src 'self' blob: filesystem: chrome-extension-resource:".*/

  var str = "";
  for(var d of domains){
    d.setTemplate(domainListingTemplate);
    str += d.render();
  }

  for(var n of $(renderTargetSelector)){
    n.innerHTML = str;
  }
}

var DOMLoaded = function() {
  if(VERBOSE){ console.debug("EVENT: DOMContentLoaded"); }
  console.log(getDomains());
  renderGraph(exampleDomains);
  renderDomainList(domains, "ul.domain-list-productive");
  var articles = ["Invasion_of_Normandy", "Banana", "Arthur_Tedder,_1st_Baron_Tedder"];
  for(var a of articles){
    fetchWikipediaArticle(a);
  }
}

document.addEventListener('DOMContentLoaded', DOMLoaded, false);
<|endoftext|>


<commit_before>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you 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.
 */
// load the master sakai object to access all Sakai OAE API methods
require(["jquery", "sakai/sakai.api.core"], function($, sakai){

    /**
     * @name sakai_global.categories
     *
     * @class categories
     *
     * @version 0.0.1
     * @param {String} tuid Unique id of the widget
     * @param {Boolean} showSettings Show the settings of the widget or not
     */
    sakai_global.categories = function(tuid, showSettings){

        // Containers
        var $categoriesItemsContainer = $("#categories_items_container");

        // Templates
        var categoriesItemsTemplate = "categories_items_template";

        // Elements
        var $categoriesExpandContract = $("#categories_expand_contract");

        var directory = sakai.config.Directory;
        var categoriesToRender = [];

        /////////////
        // BINDING //
        /////////////

        /**
         * Expand or collapse the widget
         */
        var toggleWidgetvisibility = function(){
            $categoriesItemsContainer.toggle("display");
            $categoriesExpandContract.children("div").toggle();
        };

        var addBinding = function(){
            $categoriesExpandContract.bind("click", toggleWidgetvisibility);
        };

        /**
         * Add binding to the carousel action buttons after rendering and initializing the carousel
         * @param {Object} carousel reference to the carousel instance
         */
        var carouselBinding = function(carousel){
            $(".categories_items_scroll_scrollbutton.categories_items_scroll_deselected, #categories_view_next_raquo").live("click", function(){
                $(".categories_items_scroll_scrollbutton.categories_items_scroll_deselected, #categories_view_next_raquo").die("click");
                var clickedId = parseInt($(this)[0].id.split("scroll_")[1], 10);
                if (clickedId) {
                    carousel.scroll(clickedId);
                }
                else {
                    carousel.next();
                }
                if ($(this)[0].id !== "categories_view_next_raquo") {
                    $(".categories_items_scroll_scrollbutton").addClass("categories_items_scroll_deselected");
                    $(".categories_items_scroll_selected").removeClass("categories_items_scroll_selected");
                    $(this).removeClass("categories_items_scroll_deselected");
                    $(this).addClass("categories_items_scroll_selected");
                }
                else {
                    var $this = $(".categories_items_scroll_selected");
                    if ($this.next().length) {
                        var $next = $this.next();
                        $next.addClass("categories_items_scroll_selected");
                        $next.removeClass("categories_items_scroll_deselected");
                    } else {
                        var $first = $(".categories_items_scroll_deselected:first");
                        $first.addClass("categories_items_scroll_selected");
                        $first.removeClass("categories_items_scroll_deselected");
                    }
                    $this.removeClass("categories_items_scroll_selected");
                    $this.addClass("categories_items_scroll_deselected");
                }
                return false;
            });
        };

        ////////////////////////////
        // CAROUSEL AND RENDERING //
        ////////////////////////////

        /**
         * Initialize the carousel after rendering the items
         */
        var addCarousel = function(){
            $categoriesItemsContainer.jcarousel({
                animation: "slow",
                easing: "swing",
                scroll: 4,
                wrap: "circular",
                itemFirstInCallback: carouselBinding
            });
            $categoriesItemsContainer.css("display", "none");
        };

        var renderCategories = function(){
            $categoriesItemsContainer.html(sakai.api.Util.TemplateRenderer(categoriesItemsTemplate, {
                "directory": categoriesToRender,
                "sakai": sakai
            }));
            addCarousel();
            $(".categories_widget").css("visibility", "visible");
        };

        /**
         * Parse the directory structure and extract some information from the featured content
         * @param {Object} success true or false depending on the success of loading the featured content
         * @param {Object} data contains featured content data
         */
        var parseDirectory = function(success, data){
            $.each(directory, function(i, toplevel){
                if (toplevel.divider){
                    var toFillOut = 4 - (categoriesToRender.length % 4);
                    for (var i = 0; i < toFillOut; i++){
                        categoriesToRender.push({"spacer": true});
                    }
                } else {
                    toplevel.count = 0;
                    if (data[i] && data[i].content && !$.isEmptyObject(data[i].content)){
                        toplevel.content = data[i].content;
                        toplevel.content.usedin = sakai.api.Content.getPlaceCount(toplevel.content);
                        toplevel.content.commentcount = sakai.api.Content.getCommentCount(toplevel.content);
                        toplevel.count = data[i]["sakai:tag-count"];
                    }
                    toplevel.id = i;
                    categoriesToRender.push(toplevel);
                }
            });
            var toFillOutExtra = 4 - (categoriesToRender.length % 4);
            for (var i = 0; i < toFillOutExtra; i++){
                categoriesToRender.push({"spacer": true});
            }
            renderCategories();
        };

        /**
         * Get a feed of content to display in the carousel
         */
        var getCategoryContent = function(){
            sakai.api.Server.loadJSON("/tags/directory.tagged.json", parseDirectory, {});
        };

        ////////////////
        // INITIALIZE //
        ////////////////

        var doInit = function(){
            addBinding();
            getCategoryContent();
        };

        doInit();

    };

    sakai.api.Widgets.widgetLoader.informOnLoad("categories");
});
<commit_msg>NOJIRA - Leave a gap of 1<commit_after>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you 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.
 */
// load the master sakai object to access all Sakai OAE API methods
require(["jquery", "sakai/sakai.api.core"], function($, sakai){

    /**
     * @name sakai_global.categories
     *
     * @class categories
     *
     * @version 0.0.1
     * @param {String} tuid Unique id of the widget
     * @param {Boolean} showSettings Show the settings of the widget or not
     */
    sakai_global.categories = function(tuid, showSettings){

        // Containers
        var $categoriesItemsContainer = $("#categories_items_container");

        // Templates
        var categoriesItemsTemplate = "categories_items_template";

        // Elements
        var $categoriesExpandContract = $("#categories_expand_contract");

        var directory = sakai.config.Directory;
        var categoriesToRender = [];

        /////////////
        // BINDING //
        /////////////

        /**
         * Expand or collapse the widget
         */
        var toggleWidgetvisibility = function(){
            $categoriesItemsContainer.toggle("display");
            $categoriesExpandContract.children("div").toggle();
        };

        var addBinding = function(){
            $categoriesExpandContract.bind("click", toggleWidgetvisibility);
        };

        /**
         * Add binding to the carousel action buttons after rendering and initializing the carousel
         * @param {Object} carousel reference to the carousel instance
         */
        var carouselBinding = function(carousel){
            $(".categories_items_scroll_scrollbutton.categories_items_scroll_deselected, #categories_view_next_raquo").live("click", function(){
                $(".categories_items_scroll_scrollbutton.categories_items_scroll_deselected, #categories_view_next_raquo").die("click");
                var clickedId = parseInt($(this)[0].id.split("scroll_")[1], 10);
                if (clickedId) {
                    carousel.scroll(clickedId);
                }
                else {
                    carousel.next();
                }
                if ($(this)[0].id !== "categories_view_next_raquo") {
                    $(".categories_items_scroll_scrollbutton").addClass("categories_items_scroll_deselected");
                    $(".categories_items_scroll_selected").removeClass("categories_items_scroll_selected");
                    $(this).removeClass("categories_items_scroll_deselected");
                    $(this).addClass("categories_items_scroll_selected");
                }
                else {
                    var $this = $(".categories_items_scroll_selected");
                    if ($this.next().length) {
                        var $next = $this.next();
                        $next.addClass("categories_items_scroll_selected");
                        $next.removeClass("categories_items_scroll_deselected");
                    } else {
                        var $first = $(".categories_items_scroll_deselected:first");
                        $first.addClass("categories_items_scroll_selected");
                        $first.removeClass("categories_items_scroll_deselected");
                    }
                    $this.removeClass("categories_items_scroll_selected");
                    $this.addClass("categories_items_scroll_deselected");
                }
                return false;
            });
        };

        ////////////////////////////
        // CAROUSEL AND RENDERING //
        ////////////////////////////

        /**
         * Initialize the carousel after rendering the items
         */
        var addCarousel = function(){
            $categoriesItemsContainer.jcarousel({
                animation: "slow",
                easing: "swing",
                scroll: 4,
                wrap: "circular",
                itemFirstInCallback: carouselBinding
            });
            $categoriesItemsContainer.css("display", "none");
        };

        var renderCategories = function(){
            $categoriesItemsContainer.html(sakai.api.Util.TemplateRenderer(categoriesItemsTemplate, {
                "directory": categoriesToRender,
                "sakai": sakai
            }));
            addCarousel();
            $(".categories_widget").css("visibility", "visible");
        };

        /**
         * Parse the directory structure and extract some information from the featured content
         * @param {Object} success true or false depending on the success of loading the featured content
         * @param {Object} data contains featured content data
         */
        var parseDirectory = function(success, data){
            $.each(directory, function(i, toplevel){
                if (toplevel.divider){
                    var toFillOut = 4 - (categoriesToRender.length % 4);
                    for (var i = 0; i < 1; i++){
                        categoriesToRender.push({"spacer": true});
                    }
                } else {
                    toplevel.count = 0;
                    if (data[i] && data[i].content && !$.isEmptyObject(data[i].content)){
                        toplevel.content = data[i].content;
                        toplevel.content.usedin = sakai.api.Content.getPlaceCount(toplevel.content);
                        toplevel.content.commentcount = sakai.api.Content.getCommentCount(toplevel.content);
                        toplevel.count = data[i]["sakai:tag-count"];
                    }
                    toplevel.id = i;
                    categoriesToRender.push(toplevel);
                }
            });
            var toFillOutExtra = 4 - (categoriesToRender.length % 4);
            for (var i = 0; i < toFillOutExtra; i++){
                categoriesToRender.push({"spacer": true});
            }
            renderCategories();
        };

        /**
         * Get a feed of content to display in the carousel
         */
        var getCategoryContent = function(){
            sakai.api.Server.loadJSON("/tags/directory.tagged.json", parseDirectory, {});
        };

        ////////////////
        // INITIALIZE //
        ////////////////

        var doInit = function(){
            addBinding();
            getCategoryContent();
        };

        doInit();

    };

    sakai.api.Widgets.widgetLoader.informOnLoad("categories");
});
<|endoftext|>