Skip to content

Commit

Permalink
Update image handling code
Browse files Browse the repository at this point in the history
  • Loading branch information
acbart committed Mar 14, 2022
1 parent d726336 commit 20daa21
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 29 deletions.
37 changes: 20 additions & 17 deletions lib/codemirror/python.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
var ERRORCLASS = "error";

var delimiters = parserConf.delimiters || parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.\\]/;
// (Backwards-compatiblity with old, cumbersome config system)
// (Backwards-compatibility with old, cumbersome config system)
var operators = [parserConf.singleOperators, parserConf.doubleOperators, parserConf.doubleDelimiters, parserConf.tripleDelimiters,
parserConf.operators || /^([-+*/%\/&|^]=?|[<>=]+|\/\/=?|\*\*=?|!=|[~!@]|\.\.\.)/]
for (var i = 0; i < operators.length; i++) if (!operators[i]) operators.splice(i--, 1)
Expand All @@ -62,7 +62,7 @@
var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/;
myKeywords = myKeywords.concat(["nonlocal", "False", "True", "None", "async", "await"]);
myBuiltins = myBuiltins.concat(["ascii", "bytes", "exec", "print"]);
var stringPrefixes = new RegExp("^(([rbuf]|(br)|(fr))?('{3}|\"{3}|['\"]))", "i");
var stringPrefixes = new RegExp("^(([rbuf]|(br)|(rb)|(fr)|(rf))?('{3}|\"{3}|['\"]))", "i");
} else {
var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/;
myKeywords = myKeywords.concat(["exec", "print"]);
Expand Down Expand Up @@ -98,11 +98,11 @@
return tokenBaseInner(stream, state);
}

function tokenBaseInner(stream, state) {
function tokenBaseInner(stream, state, inFormat) {
if (stream.eatSpace()) return null;

// Handle Comments
if (stream.match(/^#.*/)) return "comment";
if (!inFormat && stream.match(/^#.*/)) return "comment";

// Handle Number Literals
if (stream.match(/^[0-9\.]/, false)) {
Expand Down Expand Up @@ -177,7 +177,7 @@

// Handle non-detected items
stream.next();
return ERRORCLASS;
return inFormat ? null :ERRORCLASS;
}

function formatStringFactory(delimiter, tokenOuter) {
Expand All @@ -189,7 +189,7 @@

function tokenNestedExpr(depth) {
return function(stream, state) {
var inner = tokenBaseInner(stream, state)
var inner = tokenBaseInner(stream, state, true)
if (inner == "punctuation") {
if (stream.current() == "{") {
state.tokenize = tokenNestedExpr(depth + 1)
Expand Down Expand Up @@ -282,7 +282,7 @@
}

function pushBracketScope(stream, state, type) {
var align = stream.match(/^([\s\[\{\(]|#.*)*$/, false) ? null : stream.column() + 1
var align = stream.match(/^[\s\[\{\(]*(?:#|$)/, false) ? null : stream.column() + 1
state.scopes.push({offset: state.indent + hangingIndent,
type: type,
align: align})
Expand All @@ -298,7 +298,10 @@
}

function tokenLexer(stream, state) {
if (stream.sol()) state.beginningOfLine = true;
if (stream.sol()) {
state.beginningOfLine = true;
state.dedent = false;
}

var style = state.tokenize(stream, state);
var current = stream.current();
Expand All @@ -315,10 +318,10 @@

// Handle scope changes.
if (current == "pass" || current == "return")
state.dedent += 1;
state.dedent = true;

if (current == "lambda") state.lambda = true;
if (current == ":" && !state.lambda && top(state).type == "py")
if (current == ":" && !state.lambda && top(state).type == "py" && stream.match(/^\s*(?:#|$)/, false))
pushPyScope(state);

if (current.length == 1 && !/string|comment/.test(style)) {
Expand All @@ -332,10 +335,8 @@
else return ERRORCLASS;
}
}
if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
if (state.scopes.length > 1) state.scopes.pop();
state.dedent -= 1;
}
if (state.dedent && stream.eol() && top(state).type == "py" && state.scopes.length > 1)
state.scopes.pop();

return style;
}
Expand Down Expand Up @@ -370,14 +371,16 @@
if (state.tokenize != tokenBase)
return state.tokenize.isString ? CodeMirror.Pass : 0;

var scope = top(state), closing = scope.type == textAfter.charAt(0)
var scope = top(state)
var closing = scope.type == textAfter.charAt(0) ||
scope.type == "py" && !state.dedent && /^(else:|elif |except |finally:)/.test(textAfter)
if (scope.align != null)
return scope.align - (closing ? 1 : 0)
else
return scope.offset - (closing ? hangingIndent : 0)
},

electricInput: /^\s*[\}\]\)]$/,
electricInput: /^\s*([\}\]\)]|else:|elif |except |finally:)$/,
closeBrackets: {triples: "'\""},
lineComment: "#",
fold: "indent"
Expand All @@ -396,4 +399,4 @@
"readonly struct union DEF IF ELIF ELSE")
});

});
});
11 changes: 7 additions & 4 deletions src/ast/ast_Str.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ Blockly.Python['ast_StrChar'] = function (block) {

Blockly.Python['ast_Image'] = function (block) {
// Text value
Blockly.Python.definitions_["import_image"] = "from image import Image";
let code = "Image("+Blockly.Python.quote_(block.src_)+")";
//Blockly.Python.definitions_["import_image"] = "from image import Image";
let code = Blockly.Python.quote_(block.src_);
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
};

Expand Down Expand Up @@ -178,10 +178,13 @@ BlockMirrorTextToBlocks.prototype.dedent = function (text, levels, isDocString)
BlockMirrorTextToBlocks.prototype['ast_Str'] = function (node, parent) {
let s = node.s;
let text = Sk.ffi.remapToJs(s);
/*if (text.startsWith("http") && text.endsWith(".png")) {
const regex = BlockMirrorTextEditor.REGEX_PATTERNS[this.blockMirror.configuration.imageDetection];
//console.log(text, regex.test(JSON.stringify(text)));
if (regex.test(JSON.stringify(text))) {
//if (text.startsWith("http") && text.endsWith(".png")) {
return BlockMirrorTextToBlocks.create_block("ast_Image", node.lineno, {}, {}, {},
{"@src": text});
} else*/ if (this.isSingleChar(text)) {
} else if (this.isSingleChar(text)) {
return BlockMirrorTextToBlocks.create_block("ast_StrChar", node.lineno, {"TEXT": text});
} else if (this.isDocString(node, parent)) {
let dedented = this.dedent(text, this.levelIndex - 1, true);
Expand Down
1 change: 1 addition & 0 deletions src/block_mirror.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ BlockMirror.prototype.validateConfiguration = function (configuration) {
this.configuration.imageUploadHook = configuration.imageUploadHook || (old => Promise.resolve(old));
this.configuration.imageDownloadHook = configuration.imageDownloadHook || (old => old);
this.configuration.imageLiteralHook = configuration.imageLiteralHook || (old => old);
this.configuration.imageDetection = configuration.imageDetection || 'string';
this.configuration.imageMode = configuration.imageMode || false;
};

Expand Down
33 changes: 25 additions & 8 deletions src/text_editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ function BlockMirrorTextEditor(blockMirror) {
if (change.origin === "paste") {
let oldText = change.text[0];
if (this.isImageUrl(oldText)) {
let newText = imageLiteralHook(oldText);
let newText = this.blockMirror.configuration.imageLiteralHook(oldText);
change.update(null, null, [newText]);
}
}
Expand Down Expand Up @@ -130,9 +130,10 @@ BlockMirrorTextEditor.prototype.disableImages = function () {
BlockMirrorTextEditor.prototype.makeImageWidget = function (url) {
let newImage = document.createElement("IMG");
newImage.setAttribute("src", url);
newImage.setAttribute("height", "40");
newImage.style.display = "none";
//newImage.setAttribute("height", "40");
newImage.style.maxHeight = "100px";
newImage.setAttribute("width", "40");
//newImage.setAttribute("width", "40");
newImage.setAttribute("title", url);
newImage.onclick = (x) => {
if (newImage.hasAttribute('width')) {
Expand All @@ -143,22 +144,38 @@ BlockMirrorTextEditor.prototype.makeImageWidget = function (url) {
newImage.setAttribute("width", "40");
}
};
return newImage;
let newSpan = document.createElement("span");
newSpan.className = "cm-string";
newSpan.innerText = JSON.stringify(url);
newSpan.onmouseover = (x) => {
newImage.style.display = "block";
};
newSpan.onmouseout = (x) => {
newImage.style.display = "none";
}
newSpan.appendChild(newImage);

return newSpan;
//return newImage;
};

BlockMirrorTextEditor.prototype.updateImages = function(cm, from, to) {
cm.doc.eachLine(from, to, (line) => {
let match;
while ((match = CONSTRUCTOR_IMAGE_URL.exec(line.text)) !== null) {
const regex = BlockMirrorTextEditor.REGEX_PATTERNS[this.blockMirror.configuration.imageDetection];
while ((match = regex.exec(line.text)) !== null) {
let imageWidget = this.makeImageWidget(match[3]);
let offset = (match[0].length-match[1].length);
console.log(offset);
//console.log(offset);
let imageMarker = cm.markText({
line: cm.doc.getLineNumber(line),
ch: match.index+ offset},
{line: cm.doc.getLineNumber(line),
ch: match.index + match[1].length + offset},
{atomic: true, replacedWith: imageWidget});
{className: "bm-hyperlinked-image", attributes: {
"data-url": match[3]
}, inclusiveLeft: false, inclusiveRight: false});
console.log(imageMarker);
//imageWidget.onclick = (x) => imageMarker.clear();
this.imageMarkers.push(imageMarker);
}
Expand All @@ -169,7 +186,7 @@ BlockMirrorTextEditor.prototype.updateImages = function(cm, from, to) {
const FULL_IMAGE_URL = /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+(?:png|jpg|jpeg|gif|svg|mp4)+$/;
//const BLOB_IMAGE_URL = /(["'])(blob:null\/[A-Fa-f0-9-]+)\1/g;
//const REGULAR_IMAGE_URL = /(["'])((?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+(?:png|jpg|jpeg|gif|svg)+)\1/g;
const STRING_IMAGE_URL = /((["'])((?:blob:null\/[A-Fa-f0-9-]+)|(?:(?:https?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+(?:png|jpg|jpeg|gif|svg)+))\2)/g;
const STRING_IMAGE_URL = /((["'])((?:blob:null\/[A-Fa-f0-9-]+)|(?:(?:https?:\/\/)?[\w.-]+(?:\.?[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+(?:png|jpg|jpeg|gif|svg)+)|(?:data:image\/(?:png|jpg|jpeg|gif|svg\+xml|webp|bmp)(?:;charset=utf-8)?;base64,(?:[A-Za-z0-9]|[+/])+={0,2}))\2)/g;
//const CONSTRUCTOR_IMAGE_URL = /(?:^|\W)(Image\((["'])((?:blob:null\/[A-Fa-f0-9-]+)|(?:(?:https?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+(?:png|jpg|jpeg|gif|svg)+))\2\))/g;
const CONSTRUCTOR_IMAGE_URL = /(?:^|\W)(Image\((["'])(.+?)\2\))/g;
BlockMirrorTextEditor.REGEX_PATTERNS = {
Expand Down

0 comments on commit 20daa21

Please sign in to comment.