I have been having some issues with rangy.
the error i recieve is:
Error: Error in Rangy Serializer module: deserializePosition() failed: node
" has no child with index 3, 5"
I get this error when i pull serialized highlights from a database and try to deserialize them onto a web page. The really strange thing is most of the time the highlights are deserialized just fine and display on the page but at times they randomly disappear and I get the above mentioned error.
I used the chrome javascript debugger to track down the issue and
function deserializePosition(serialized, rootNode, doc) {
if (!rootNode) {
rootNode = (doc || document).documentElement;
}
var parts = serialized.split(":");
var node = rootNode;
var nodeIndices = parts[0] ? parts[0].split("/") : [], i = nodeIndices.length, nodeIndex;
while (i--) {
nodeIndex = parseInt(nodeIndices[i], 10);
if (nodeIndex < node.childNodes.length) {
node = node.childNodes[nodeIndex];
} else {
throw module.createError("deserializePosition() failed: node " + dom.inspectNode(node) +
" has no child with index " + nodeIndex + ", " + i);
}
}
return new dom.DomPosition(node, parseInt(parts[1], 10));
}
in this code block for some reason at the line
var node = rootNode;
even though rootNode = html, the variable node gets assigned 'text' sometimes and this causes the node.childNodes.length to be equal to 0 and an error is thrown. Any help would be much appreciated, thanks.
Related
I am debugging a Webpack build by using node --inspect and Chrome DevTools.
I see that my output file contains a piece of code with the comment /* WEBPACK VAR INJECTION */. If I put a break point right at the Webpack code that generates that comment, the debugger won't stop at that breakpoint when running the build in debug mode, but it stops when I place debugger;. Why?
EDIT:
The (last version of the) code I am referring to can be seen in
https://github.com/webpack/webpack/blob/master/lib/NormalModule.js
Here I paste an extract. I expected the debugger to stop at any breakpoint I put inside this function (except inside places like the function passed to .map and .forEach). (This is the only piece of code in Webpack that writes /* WEBPACK VAR INJECTION */):
function doBlock(block) {
console.log("1 What the F*** is going on with this debugger?");
block.dependencies.forEach(doDep);
block.blocks.forEach(doBlock);
if(block.variables.length > 0) {
var vars = [];
block.variables.forEach(doVariable.bind(null, vars));
var varNames = [];
var varExpressions = [];
var varStartCode = "";
var varEndCode = "";
function emitFunction() {
console.log("2 Why the F*** is it that a breakpoint right here doesn't stop the debugger?");
if(varNames.length === 0) return;
varStartCode += "/* WEBPACK VAR INJECTION */(function(" + varNames.join(", ") + ") {";
// exports === this in the topLevelBlock, but exports do compress better...
varEndCode = (topLevelBlock === block ? "}.call(exports, " : "}.call(this, ") +
varExpressions.map(function(e) {
return e.source();
}).join(", ") + "))" + varEndCode;
varNames.length = 0;
varExpressions.length = 0;
}
vars.forEach(function(v) {
if(varNames.indexOf(v.name) >= 0) emitFunction();
varNames.push(v.name);
varExpressions.push(v.expression);
});
emitFunction();
console.log("3 Are you not gonna stop here, debugger? Are you F****** kidding me?");
var start = block.range ? block.range[0] : 0;
var end = block.range ? block.range[1] : _source.size();
if(varStartCode) source.insert(start + 0.5, varStartCode);
if(varEndCode) source.insert(end + 0.5, "\n/* WEBPACK VAR INJECTION */" + varEndCode);
}
}
I've created a protractor test for the following html:
<div class="well well-sm" data-ng-repeat="feedback in f.feedbackList">
Rating: {{feedback.rating}}
<blockquote class="small">{{feedback.comment}}</blockquote>
</div>
In the page.js file I have:
"use strict";
module.exports = (function () {
function AdminFeedbackPage() {
this.comments = element.all(by.repeater('feedback in f.feedbackList').column('feedback.comment')).map(function (comments) {
return comments.getText();
});
this.ratings = element.all(by.repeater('feedback in f.feedbackList').column('feedback.rating')).map(function (ratings) {
return ratings.getText();
});
}
return AdminFeedbackPage; })();
and then in the test in my step.js file:
var feedbackFound = false;
var feedbackIndex;
adminFeedbackPage.comments.then(function (commments) {
for (var i = 0; i < commments.length; i++) {
console.log("Comments " + i + ": " + commments[i]);
if (commments[i] == "TestApplicationFeedback") {
feedbackIndex = i;
console.log("FEEDBACK INDEX - " + feedbackIndex)
feedbackFound = true;
break;
}
}
}).then(function () {
expect(feedbackFound).to.be.true;
}).then(function() {
adminFeedbackPage.ratings.then(function (ratings) {
console.log(ratings);
console.log("RATINGS length " + ratings.length + " and rating is " + ratings[feedbackIndex]);
expect(ratings[feedbackIndex]).to.equal(3);
})
});
And I get the following logs:
Comments 0: Decent App
Comments 1: Really like it
Comments 2: TestApplicationFeedback
FEEDBACK INDEX - 2
[]
RATINGS length 0 and rating is undefined
AssertionError: expected undefined to equal 3
This is really confusing my since the comments are being found without any issue, but the ratings are just an empty array and as far as I can tell I have done the same thing for both.
Does anybody have any suggestions/reasons why the ratings aren't being found? I suspect it's something to do with what is in the page.js file, but I have no idea what could be wrong?
Thanks!
Solved this in the comments above, posting as an answer:
It was just a guess/suggestion based on the HTML, one was a child element and the other was directly inside the repeater (this one was failing to be captured). So my suggestion was to try using .evaluate() source, which acts as if on scope of the given element. So replacing .column() seems to work:
element.all(by.repeater('feedback in f.feedbackList')).evaluate('feedback.rating').then(function(val) {
console.log(val) // should return an array of values (feedback.rating)
})
I am trying to get the data from Firebird DB with sequentially select option. I would like to get the first 500 rows, as you see on my code. And for testing, I am increasing 'k' for each 'row' and logging 'k' and
'md5' to the console.
When I am running my code, it gives me random number of rows. But the number of rows are always more than 500.
How can I solve this problem? Any suggestions?
var Firebird = require('node-firebird');
var md5 = require('md5');
var options = {};
//options.host = '127.0.0.1';
//options.port = 3050;
options.database = '/Users/bla/mydb.FDB';
options.user = 'SYSDBA';
options.password = 'masterkey';
var pool = Firebird.pool(10, options);
var k = 0;
pool.get(function (err, db) {
if (err)
throw err;
db.sequentially('SELECT FIRST 500 SOME QUERY', function (row, index) {
k = k + 1;
console.log(k + ' => ' + md5(JSON.stringify(row)) + '\n');
}, function (err) {
db.detach();
});
});
Please check the link above:
https://github.com/hgourvest/node-firebird/issues/78
#sdnetwork sdnetwork commented an hour ago it's a bug in node-firebird, i have a fix for this problem. i will post it soon here. (try with that https://github.com/sdnetwork/node-firebird)
depending upon the version of firebird, "select first n" may give an error unless you also include an "order by" clause
I'm going to try to explain this as best I can, please feel free to ask for clarifications as required.
Using IE10, CRM Online with RU12.
I am playing about with subgrids and getting them to refresh. Consider the following script, which I have nicked wholesale from MSDN (and wrapped in a try/catch block)
function start() {
try {
var controls = Xrm.Page.ui.controls.get(isSubGrid);
if (controls.length > 0) {
var subGridNames = "";
for (var i in controls) {
controls[i].refresh();
subGridNames += (" - " + controls[i].getName() + "\n");
}
alert("The following subgrids were refreshed: \n" + subGridNames);
}
else {
alert("There are no subgrid controls on the current form.");
}
}
catch (ex) {
alert(ex);
}
}
function isSubGrid (control)
{
return control.getControlType() == "subgrid";
}
Nothing special going on there - get all controls of type subgrid (this returns 10 elements as expected) and call refresh() on them.
However this is consistently failing on the first call to refresh().
The exception details is fairly straightforward
TypeError: Unable to get property 'Refresh' of undefined or null reference
Which suggests that the control[i] is null when called in the loop at this point here
for (var i in controls) {
controls[i].refresh();//error thrown here - suggests controls[i] is null
subGridNames += (" - " + controls[i].getName() + "\n");
}
However I can see that it isn't null (and has the method refresh as expected).
I can make it work by using setInterval
function waitAndThenRefresh(gridname) {
var grid = Xrm.Page.ui.controls.get(gridname);
var intervalId = setInterval(function () {
if (grid === null || grid._control === null || grid._control._element === null) {
return;
}
if (grid._control._element.readyState === 'complete') {
window.clearInterval(intervalId);
if (grid != null) {
grid.refresh();
}
}
}, 1000);
}
But that is pretty hideous, not to mention does not explain with the SDK call doesn't work as expected.
So I guess the question is: has anyone else seen this issue? Or can you replicate it on another instance? Am I missing something? There is nothing in the SDK that suggests you need to defer calling refresh until the inner control's readyState is complete?
The code block you are using,
for (var i in controls) {
controls[i].refresh();
subGridNames += (" - " + controls[i].getName() + "\n");
}
should be replaced with the following:
for (var i in controls) {
i.refresh();
subGridNames += (" - " + i.getName() + "\n");
}
or:
for (var i = 0; i < controls.length; i++) {
controls[i].refresh();
subGridNames += (" - " + controls[i].getName() + "\n");
}
You are getting the exception because controls[i] is undefined in your case, i being the control (the element of the array controls).
I asked a CRM-buddy of mine. He said that the issue depends on the new refreshment Engine. According to him, it's sort of a bug but not really. If I got it right, the refresh has been reengineered to accommodate the new perpetual saving functionality.
I was trying my hand at Windows shell scripting using cscript and Javascript. The idea was to take a really long Python command that I was tired of typing into the command line over and over. What I wanted to do was write a script that is much shorter to write the whole Python command into a Windows script and just call the Windows script, which would be a lot less to type. I just don't know how I would go about calling a "command within a command" if that makes sense.
This is probably an easy thing, but I'm an newbie at this so please bear with me!
The idea:
Example original command: python do <something really complicated with a long filepath>
Windows Script: cscript easycommand
<package id = "easycommand">
<job id = "main" >
<script type="text/javascript">
// WHAT GOES HERE TO CALL python do <something really complicated>
WScript.Echo("Success!");
</script>
</job>
</package>
Thanks for all your help!
Here's what I use
function logMessage(msg) {
if (typeof wantLogging != "undefined" && wantLogging) {
WScript.Echo(msg);
}
}
// http://msdn.microsoft.com/en-us/library/d5fk67ky(VS.85).aspx
var windowStyle = {
hidden : 0,
minimized : 1,
maximized : 2
};
// http://msdn.microsoft.com/en-us/library/a72y2t1c(v=VS.85).aspx
var specialFolders = {
windowsFolder : 0,
systemFolder : 1,
temporaryFolder : 2
};
function runShellCmd(command, deleteOutput) {
deleteOutput = deleteOutput || false;
logMessage("RunAppCmd("+command+") ENTER");
var shell = new ActiveXObject("WScript.Shell"),
fso = new ActiveXObject("Scripting.FileSystemObject"),
tmpdir = fso.GetSpecialFolder(specialFolders.temporaryFolder),
tmpFileName = fso.BuildPath(tmpdir, fso.GetTempName()),
rc;
logMessage("shell.Run("+command+")");
// use cmd.exe to redirect the output
rc = shell.Run("%comspec% /c " + command + "> " + tmpFileName,
windowStyle.Hidden, true);
logMessage("shell.Run rc = " + rc);
if (deleteOutput) {
fso.DeleteFile(tmpFileName);
}
return {
rc : rc,
outputfile : (deleteOutput) ? null : tmpFileName
};
}
Here's an example of how to use the above to list the Sites defined in IIS with Appcmd.exe:
var
fso = new ActiveXObject("Scripting.FileSystemObject"),
windir = fso.GetSpecialFolder(specialFolders.WindowsFolder),
r = runShellCmd("%windir%\\system32\\inetsrv\\appcmd.exe list sites");
if (r.rc !== 0) {
// 0x80004005 == E_FAIL
throw {error: "ApplicationException",
message: "shell.run returned nonzero rc ("+r.rc+")",
code: 0x80004005};
}
// results are in r.outputfile
var
textStream = fso.OpenTextFile(r.outputfile, OpenMode.ForReading),
sites = [], item,
re = new RegExp('^SITE "([^"]+)" \\((.+)\\) *$'),
parseOneLine = function(oneLine) {
// each line is like this: APP "kjsksj" (dkjsdkjd)
var tokens = re.exec(oneLine), parts;
if (tokens === null) {
return null;
}
// return the object describing the website
return {
name : tokens[1]
};
};
// Read from the file and parse the results.
while (!textStream.AtEndOfStream) {
item = parseOneLine(textStream.ReadLine()); // you create this...
logMessage(" site: " + item.name);
sites.push(item);
}
textStream.Close();
fso.DeleteFile(r.outputfile);
Well, basically:
Obtain a handle to the shell so you can execute your script
Create the command you want to execute (parameters and all) as a string
Call the Run method on the shell handle, and figure out which window mode you want and also whether you want to wait until the spawned process finishes (probably) or not.
Error handling because Run throws exceptions
At this point it's worth writing a lot of utility functions if ever you need to do it more than once:
// run a command, call: run('C:\Python27\python.exe', 'path/to/script.py', 'arg1', 'arg2') etc.
function run() {
try {
var cmd = "\"" + arguments[0] + "\"";
var arg;
for(var i=1; i< arguments.length; ++i) {
arg = "" + arguments[i];
if(arg.length > 0) {
cmd += arg.charAt(0) == "/" ? (" " + arg) : (" \"" + arg + "\"");
}
}
return getShell().Run(cmd, 1, true); // show window, wait until done
}
catch(oops) {
WScript.Echo("Error: unable to execute shell command:\n"+cmd+
"\nInside directory:\n" + pwd()+
"\nReason:\n"+err_message(oops)+
"\nThis script will exit.");
exit(121);
}
}
// utility which makes an attempt at retrieving error messages from JScript exceptions
function err_message(err_object) {
if(typeof(err_object.message) != 'undefined') {
return err_object.message;
}
if(typeof(err_object.description) != 'undefined') {
return err_object.description;
}
return err_object.name;
}
// don't create new Shell objects each time you call run()
function getShell() {
var sh = WScript.CreateObject("WScript.Shell");
getShell = function() {
return sh;
};
return getShell();
}
For your use case this may be sufficient, but you might want to extend this with routines to change working directory and so on.