summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <daniel.silverstone@codethink.co.uk>2016-07-07 16:19:17 +0100
committerDaniel Silverstone <daniel.silverstone@codethink.co.uk>2016-07-07 16:19:17 +0100
commit285f8f0d7388dee36bf97f25e26db1f42bcf0db4 (patch)
tree6dc19aab6aa5f6300f50999dbe5365bbc23e82b7
parentd0c7ba1fe3d271d44411287648d9363d35ff15be (diff)
downloadsievely-285f8f0d7388dee36bf97f25e26db1f42bcf0db4.tar.bz2
Basic blocks and test
-rw-r--r--sievely/blocks.js321
-rw-r--r--test.html133
2 files changed, 454 insertions, 0 deletions
diff --git a/sievely/blocks.js b/sievely/blocks.js
new file mode 100644
index 0000000..5f30037
--- /dev/null
+++ b/sievely/blocks.js
@@ -0,0 +1,321 @@
+/*
+ * Sievely blocks
+ * Copyright 2016 Daniel Silverstone <daniel.silverstone@codethink.co.uk>
+ *
+ * See COPYING
+ */
+
+'use strict';
+
+goog.provide('Sievely.Blocks')
+
+goog.require('Blockly.Blocks')
+
+Sievely.Blocks.STATEMENT_HUE = 120;
+Sievely.Blocks.COMMENT_HUE = 165;
+Sievely.Blocks.BOOLEAN_HUE = 330;
+Sievely.Blocks.ACTION_HUE = 230;
+Sievely.Blocks.ADJUSTOR_HUE = 20;
+
+Sievely.Blocks.HELP_URL = "https://somewhere/sievely";
+
+Blockly.Blocks['sievely_start'] = {
+ init: function() {
+ this.appendDummyInput()
+ .appendField("When a message arrives:");
+ this.setNextStatement(true, null);
+ this.setColour(Sievely.Blocks.STATEMENT_HUE);
+ this.setTooltip('');
+ this.setHelpUrl(Sievely.Blocks.HELP_URL);
+ }
+};
+
+Blockly.Blocks['sievely_comment'] = {
+ init: function() {
+ this.appendDummyInput()
+ .appendField("/*")
+ .appendField(new Blockly.FieldTextInput("comment"), "COMMENT")
+ .appendField("*/");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(Sievely.Blocks.COMMENT_HUE);
+ this.setTooltip('');
+ this.setHelpUrl(Sievely.Blocks.HELP_URL);
+ }
+};
+
+/* Matches */
+
+Blockly.Blocks['sievely_listcheck'] = {
+ init: function() {
+ this.appendValueInput("LISTNAME")
+ .setCheck("String")
+ .appendField("from mailing list");
+ this.setOutput(true, "Boolean");
+ this.setColour(Sievely.Blocks.BOOLEAN_HUE);
+ this.setTooltip('');
+ this.setHelpUrl(Sievely.Blocks.HELP_URL);
+ }
+};
+
+Blockly.Blocks['sievely_isfrom'] = {
+ init: function() {
+ this.appendValueInput("ADDR")
+ .setCheck("String")
+ .appendField("message is from");
+ this.setOutput(true, "Boolean");
+ this.setColour(Sievely.Blocks.BOOLEAN_HUE);
+ this.setTooltip('');
+ this.setHelpUrl(Sievely.Blocks.HELP_URL);
+ }
+};
+
+Blockly.Blocks['sievely_envelope_detail'] = {
+ init: function() {
+ this.appendValueInput("DETAIL")
+ .setCheck("String")
+ .appendField("addressee suffix is");
+ this.setOutput(true, "Boolean");
+ this.setColour(Sievely.Blocks.BOOLEAN_HUE);
+ this.setTooltip('');
+ this.setHelpUrl(Sievely.Blocks.HELP_URL);
+ }
+};
+
+Blockly.Blocks['sievely_header_test'] = {
+ init: function() {
+ this.appendValueInput("HEADER")
+ .setCheck("Header");
+ this.appendValueInput("CONTENT")
+ .setCheck("String")
+ .appendField(new Blockly.FieldDropdown([["contains", "CONTAINS"], ["is", "IS"], ["matches", "MATCHES"]]), "MATCH");
+ this.setInputsInline(true);
+ this.setOutput(true, "Boolean");
+ this.setColour(Sievely.Blocks.BOOLEAN_HUE);
+ this.setTooltip('');
+ this.setHelpUrl(Sievely.Blocks.HELP_URL);
+ }
+};
+
+Blockly.Blocks['sievely_header'] = {
+ init: function() {
+ this.appendDummyInput()
+ .appendField("the")
+ .appendField(new Blockly.FieldTextInput("Subject"), "HEADER")
+ .appendField("header");
+ this.setOutput(true, "Header");
+ this.setColour(Blockly.Blocks.texts.HUE);
+ this.setTooltip('');
+ this.setHelpUrl('http://www.example.com/');
+ }
+};
+
+/* Actions */
+
+Blockly.Blocks['sievely_fileinto'] = {
+ init: function() {
+ this.appendValueInput("MAILBOX")
+ .setCheck("String")
+ .appendField("file into");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(Sievely.Blocks.ACTION_HUE);
+ this.setTooltip('');
+ this.setHelpUrl(Sievely.Blocks.HELP_URL);
+ }
+};
+
+Blockly.Blocks['sievely_filecopyinto'] = {
+ init: function() {
+ this.appendValueInput("MAILBOX")
+ .setCheck("String")
+ .appendField("file a copy into");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(Sievely.Blocks.ACTION_HUE);
+ this.setTooltip('');
+ this.setHelpUrl(Sievely.Blocks.HELP_URL);
+ }
+};
+Blockly.Blocks['sievely_reject'] = {
+ init: function() {
+ this.appendValueInput("REASON")
+ .setCheck("String")
+ .appendField("reject saying");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(Sievely.Blocks.ACTION_HUE);
+ this.setTooltip('');
+ this.setHelpUrl(Sievely.Blocks.HELP_URL);
+ }
+};
+
+Blockly.Blocks['sievely_stop'] = {
+ init: function() {
+ this.appendDummyInput()
+ .appendField("stop processing here");
+ this.setPreviousStatement(true, null);
+ this.setColour(Sievely.Blocks.ACTION_HUE);
+ this.setTooltip('');
+ this.setHelpUrl(Sievely.Blocks.HELP_URL);
+ }
+};
+
+Blockly.Blocks['sievely_discard'] = {
+ init: function() {
+ this.appendDummyInput()
+ .appendField("discard message and stop processing here");
+ this.setPreviousStatement(true, null);
+ this.setColour(Sievely.Blocks.ACTION_HUE);
+ this.setTooltip('');
+ this.setHelpUrl(Sievely.Blocks.HELP_URL);
+ }
+};
+
+/* Adjustor blocks */
+
+Blockly.Blocks['sievely_mark'] = {
+ init: function() {
+ this.appendDummyInput()
+ .appendField("Mark message as")
+ .appendField(new Blockly.FieldDropdown([["already read", "Seen"], ["unread", "!Seen"], ["high priority", "Flagged"], ["normal priority", "!Flagged"], ["already answered", "Answered"], ["unanswered", "!Answered"]]), "MARK");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(Sievely.Blocks.ADJUSTOR_HUE);
+ this.setTooltip('');
+ this.setHelpUrl(Sievely.Blocks.HELP_URL);
+ }
+};
+
+/* Special groups */
+
+Blockly.Blocks['sievely_group'] = {
+ init: function() {
+ this.appendValueInput("COND0")
+ .setCheck("Boolean")
+ .setAlign(Blockly.ALIGN_RIGHT)
+ .appendField(new Blockly.FieldDropdown([["any of", "ANYOF"], ["all of", "ALLOF"]]), "KIND");
+ this.appendValueInput("COND1")
+ .setCheck("Boolean")
+ .setAlign(Blockly.ALIGN_RIGHT)
+ .appendField("or");
+ this.setOutput(true, "Boolean");
+ this.setColour(Sievely.Blocks.BOOLEAN_HUE);
+ this.setTooltip('');
+ this.setHelpUrl(Sievely.Blocks.HELP_URL);
+ this.setMutator(new Blockly.Mutator(['sievely_group_extra']));
+ this.extras_ = 0;
+ },
+ mutationToDom: function() {
+ if (this.extras_ == 0) {
+ return null;
+ }
+ var container = document.createElement('mutation');
+ container.setAttribute('extras', this.extras_);
+ return container;
+ },
+ domToMutation: function(xmlElement) {
+ this.extras_ = parseInt(xmlElement.getAttribute('extras'), 10) || 0;
+ this.updateShape_();
+ },
+ decompose: function(workspace) {
+ var containerBlock = workspace.newBlock('sievely_group_group');
+ containerBlock.initSvg();
+ var connection = containerBlock.nextConnection;
+ for (var i = 1; i <= this.extras_; i++) {
+ var extraBlock = workspace.newBlock('sievely_group_extra');
+ extraBlock.initSvg();
+ connection.connect(extraBlock.previousConnection);
+ connection = extraBlock.nextConnection;
+ }
+ return containerBlock;
+ },
+ compose: function(containerBlock) {
+ var clauseBlock = containerBlock.nextConnection.targetBlock();
+ // Count number of inputs.
+ this.extras_ = 0;
+ var valueConnections = [null];
+ while (clauseBlock) {
+ switch (clauseBlock.type) {
+ case 'sievely_group_extra':
+ this.extras_++;
+ valueConnections.push(clauseBlock.valueConnection_);
+ break;
+ default:
+ throw 'Unknown block type.';
+ }
+ clauseBlock = clauseBlock.nextConnection &&
+ clauseBlock.nextConnection.targetBlock();
+ }
+ this.updateShape_();
+ // Reconnect any child blocks.
+ for (var i = 1; i <= this.extras_; i++) {
+ Blockly.Mutator.reconnect(valueConnections[i], this, 'COND' + (i+1));
+ }
+ },
+ saveConnections: function(containerBlock) {
+ var clauseBlock = containerBlock.nextConnection.targetBlock();
+ var i = 2;
+ while (clauseBlock) {
+ switch (clauseBlock.type) {
+ case 'sievely_group_extra':
+ var cond = this.getInput('COND' + i)
+ clauseBlock.valueConnection_ =
+ cond && cond.connection.targetConnection;
+ i++;
+ break;
+ default:
+ throw 'Unknown block type.';
+ }
+ clauseBlock = clauseBlock.nextConnection &&
+ clauseBlock.nextConnection.targetBlock();
+ }
+ },
+ updateShape_: function() {
+ // Delete everything.
+ var i = 2;
+ while (this.getInput('COND' + i)) {
+ this.removeInput('COND' + i);
+ i++;
+ }
+ // Rebuild block.
+ for (var i = 1; i <= this.extras_; i++) {
+ this.appendValueInput('COND' + (i+1))
+ .setCheck('Boolean')
+ .setAlign(Blockly.ALIGN_RIGHT)
+ .appendField(this.andor_);
+ }
+ },
+ onchange: function(changeEvent) {
+ var kind = this.getField('KIND').getValue();
+ this.andor_ = (kind == "ANYOF") ? "or" : "and";
+ for (var i = 1; i < this.inputList.length; i++) {
+ var f = this.inputList[i].fieldRow.pop();
+ f.dispose();
+ this.inputList[i].appendField(this.andor_);
+ }
+ }
+};
+
+Blockly.Blocks['sievely_group_group'] = {
+ init: function() {
+ this.appendDummyInput()
+ .appendField("group");
+ this.setNextStatement(true, null);
+ this.setColour(Sievely.Blocks.BOOLEAN_HUE);
+ this.setTooltip('');
+ this.setHelpUrl(Sievely.Blocks.HELP_URL);
+ }
+};
+
+Blockly.Blocks['sievely_group_extra'] = {
+ init: function() {
+ this.appendDummyInput()
+ .appendField("additional test");
+ this.setPreviousStatement(true, null);
+ this.setNextStatement(true, null);
+ this.setColour(Sievely.Blocks.BOOLEAN_HUE);
+ this.setTooltip('');
+ this.setHelpUrl(Sievely.Blocks.HELP_URL);
+ }
+};
diff --git a/test.html b/test.html
new file mode 100644
index 0000000..8c91f50
--- /dev/null
+++ b/test.html
@@ -0,0 +1,133 @@
+<html>
+ <head>
+ <title>Simple Sievely test</title>
+ <script src="google/blockly/blockly_compressed.js"></script>
+ <script src="google/blockly/blocks_compressed.js"></script>
+ <script src="google/blockly/msg/js/en.js"></script>
+ <script src="sievely/blocks.js"></script>
+ </head>
+ <body>
+ <div id="blocklyDiv" style="height: 600px; width: 800px;"></div>
+
+ <xml id="toolbox" style="display: none">
+ <category name="Logic">
+ <block type="controls_if"></block>
+ <block type="controls_if">
+ <mutation else="1"></mutation>
+ </block>
+ <block type="controls_if">
+ <mutation elseif="1" else="1"></mutation>
+ </block>
+ <sep></sep>
+ <block type="sievely_group">
+ </block>
+ </category>
+ </category>
+ <category name="Matches">
+ <block type="sievely_listcheck">
+ <value name="LISTNAME">
+ <shadow type="text">
+ <field name="TEXT">listname.listdomain.com</field>
+ </shadow>
+ </value>
+ </block>
+ <block type="sievely_isfrom">
+ <value name="ADDR">
+ <shadow type="text">
+ <field name="TEXT">someone@another.domain.com</field>
+ </shadow>
+ </value>
+ </block>
+ <block type="sievely_envelope_detail">
+ <value name="DETAIL">
+ <shadow type="text">
+ <field name="TEXT">todo</field>
+ </shadow>
+ </value>
+ </block>
+ <block type="sievely_header_test">
+ <value name="HEADER">
+ <shadow type="sievely_header">
+ <field name="HEADER">Subject</field>
+ </shadow>
+ </value>
+ <field name="MATCH">CONTAINS</field>
+ <value name="CONTENT">
+ <shadow type="text">
+ <field name="TEXT">Alert</field>
+ </shadow>
+ </value>
+ </block>
+ </category>
+ <category name="Headers and Values">
+ <block type="sievely_header">
+ <field name="HEADER">Subject</field>
+ </block>
+ <block type="sievely_header">
+ <field name="HEADER">To</field>
+ </block>
+ <block type="sievely_header">
+ <field name="HEADER">Cc</field>
+ </block>
+ <block type="text"></block>
+ </category>
+ <category name="Actions">
+ <category name="Message flags">
+ <block type="sievely_mark">
+ <field name="MARK">Seen</field>
+ </block>
+ <block type="sievely_mark">
+ <field name="MARK">Important</field>
+ </block>
+ </category>
+ <category name="Processing Actions">
+ <block type="sievely_stop"></block>
+ <block type="sievely_discard"></block>
+ <sep></sep>
+ <block type="sievely_fileinto">
+ <value name="MAILBOX">
+ <block type="text">
+ <field name="TEXT">FolderName</field>
+ </block>
+ </value>
+ <next>
+ <block type="sievely_stop"></block>
+ </next>
+ </block>
+ <block type="sievely_filecopyinto">
+ <value name="MAILBOX">
+ <block type="text">
+ <field name="TEXT">AnotherFolderName</field>
+ </block>
+ </value>
+ <next>
+ <block type="sievely_stop"></block>
+ </next>
+ </block>
+ <block type="sievely_reject">
+ <value name="REASON">
+ <block type="text">
+ <field name="TEXT">I do not wish to accept this message.</field>
+ </block>
+ </value>
+ <next>
+ <block type="sievely_stop"></block>
+ </next>
+ </block>
+ </category>
+ </category>
+ </xml>
+
+ <xml id="startblocks" style="display: none">
+ <block type="sievely_start" deletable="false" x="20" y="20">
+ </block>
+ </xml>
+ <script>
+ var workspace = Blockly.inject('blocklyDiv',
+ {toolbox: document.getElementById('toolbox')});
+ Blockly.Xml.domToWorkspace(document.getElementById('startblocks'),
+ workspace)
+ workspace.addChangeListener(Blockly.Events.disableOrphans);
+ </script>
+ </body>
+</html>