How to prevent automatic hyperlink detection in the console of Firefox/Chrome developer tools? - hyperlink

Something that drives me nuts in the developper tools of Chrome (106) and Firefox (105) is the fact that whenever some text logged to the console via console.log(text) happens to contain a hyperlink, this link is not only turned clickable (I can live with it even when I usually prefer to have just plain text) but is abbreviated, if it is a long link. So when I want to control what precise link is in some variable, I cannot just write e.g. console.log(img.src), because some of the interesting information of the link is hidden.
You can try yourself with
var href = 'https://stackoverflow.com/search?q=%5Bgoogle-chrome-devtools%5D+%5Bconsole.log%5D+%5Bfirefox-developer-tools%5D+%5Bhyperlink%5D+automatic+detection&someMoreStuffTomakeTheLinkLonger';
console.log(href);
In both, Firefox and Chrome, the output for me contains some '...', e.g. in Firefox I obtain as output:
https://stackoverflow.com/search?q=%5Bgoogle-chrome-devtools…link%5D+automatic+detection&someMoreStuffTomakeTheLinkLonger
thus hiding the part after "-devtools". (Chrome hides a slightly different part). The console is mostly a debugging tool. I log things because I want to see them, not hide them. I always need to either hover with the mouse and wait for the tooltip (doesn't allow me to copy fractions of the link) or to right click copy the link and paste it somewhere where I can see it completely. Or take a substring to remove the "https://" in the front. But note that the variable isn't necessarily a single hyperlink, but can be any text containing several such hyperlinks. I didn't find a way to force console.log to just print plain text all content. Did anybody meet this problem as well and find a workaround?

I made this a community wiki answer, because the main insight is not from myself but from the comments. Feel free to improve.
The console.log() function allows several arguments, which allows also a formatted output similar to printf in some languages. The possibilities of formatting can be found in the documentation of console.log() on MDN. In any case, this formatted output provides a solution at least for Chrome, as #wOxxOm pointed out in the comments:
console.log('%O', href) // works in Chrome
This is rather surprising, because %O is described at MDN as
"Outputs a JavaScript object. Clicking the object name opens more information about it in the inspector".
It seems there is no 'clicking' in Chrome when the object is a string.
There is also %s for string output, but this just gives the standard behavior of replacing links in both browsers. And for Firefox none of the above two formatting options works. There one really has to replace the protocol "https://" by something that is not recognized as link. A space behind ':' seems enough, so "https: //". It turns out, that one can also insert a formatting string "https:%c//", which can even be empty, and thus yield an output which is the complete link and can be copied as well:
console.log(href.replace(/(https?:)/, "$1%c"), ""); // works in Firefox
In particular the FF solution is cumbersome, and there might also be several links within one console-output. So it is useful to define one's own log-function (or if one prefers, redefine console.log, but note the remark at the end)
function isChrome() {...} // use your favorite Chrome detection here
function isFirefox() {...} // use your favorite Firefox detection here
function plainLog() {
const msg = arguments[0];
if (isChrome() && arguments.length == 1 && typeof msg == "string") {
return console.log("%O", msg);
}
if (isFirefox() && arguments.length == 1 && typeof msg == "string") {
const emptyStyle = ""; // serves only as a separator, such that FF doesn't recognize the link anymore
const reg = /(https?:)\/\//g;
const emptyStyles = []; // we need to insert one empty Style for every found link
const matches = msg.matchAll(reg);
for (let match of matches) {
emptyStyles.push(emptyStyle);
}
return console.log(msg.replace(reg, '$1%c//'), ...emptyStyles);
}
return console.log(...arguments);
}
For browser detection isChrome() and isFirefox() see e.g. here on SO.
One can of course extend the redefinition also to the other console functions (console.info, console.warn, etc.)
The downside of the redefinition of console.log is that usually every output of the console shows also the last entry of the call stack as a practical link to the source of the logging. But due to the redefintion, this link is now always to the same place, namely the file and line number where plainLog() is defined and calls console.log(), instead of the place where the new log command plainLog() was called. This new problem is described on SO here, but the solution (see comment) is again a bit involved and also not completely satisfying to serve as a replacement for the built-in console.log . So if links appear only rarely in the logging, it's probably better to switch to the redefined plainLog() only for these links.

Related

Aspose generated doc file turns underscores into white space for some users

I am updating archaic code that creates memos. The code was written to use bookmarks inside of manually created template.doc files that aspose can write to. The problem comes from this chunk of code.
foreach (Addressee infoAddressee in ConfigManager.GetConfig().Addressees)
{
if (infoAddressee.Abbreviation == Memo.AddresseeAbbr.ToUpper() &&
infoAddressee.NeedsThisLine)
{
WriteMeString = "FOO BARR ________";
break;
}
}
if (WriteMeString != "")
{
builder.MoveToBookmark("BOOKMARK");
builder.Write(WriteMeString);
}
}
This works for me, but the two people who have tested this chunk of code have the "FOO BARR _______" line appear as "FOO BARR "
the seven underlines are replaced with spaces(the spacing exists on the word doc, but Stack overflow concatenates consecutive spaces). I am not sure what could cause this.
To test we need to copy the file from the remote dev environment into our local environment, I believe this to be the source of the issue, but i do not know for sure.
What I have already tried:
The testers and me are supplying the exact same input for the document.
The testers and I had a slightly different way to save the document and copy paste it over to the local environment, but doing it my way did not change anything.
I am unsure of what could do this for some users but not for others, any suggestions for things i could check out, be it literature with information on the subject or proposed solutions, would be greatly appreciated
I checked the scenario on my side and cannot reproduce the problem. Underscores are properly displayed in the output document. Here are few things to try.
Try setting bookmark text instead of moving to it and writing text.
doc.Range.Bookmarks["BOOKMARK"].Text = WriteMeString;
Try checking whether string is written correctly into the document.
builder.MoveToBookmark("BOOKMARK");
builder.Write("FOO BARR ________");
Assert.AreEqual("FOO BARR ________", builder.Document.Range.Bookmarks["BOOKMARK"].Text);
using (MemoryStream ms = new MemoryStream())
{
builder.Document.Save(ms, SaveFormat.Doc);
ms.Position = 0;
Document tempDoc = new Document(ms);
Assert.AreEqual("FOO BARR ________", tempDoc.Range.Bookmarks["BOOKMARK"].Text);
}
Compare the documents produced on your side and on the testers side yourself (I suppose, you have already done this, but just in case). Probably the documents are correct, but there is difference in viewer used on your and testers side.
Disclosure: I work at Aspose.Words team.

Zebra Printer - Cut on last page

I've a Zebra ZT610 and I want to print a label, in pdf format, containing multiple pages and then have it cut on the last page. I've tried using the delayed cut mode and sending the ~JK command but I'm using a self written java application to do the invocation of printing. I've also tried to add the string "${^XB}$" into the PDF document before each page break, except the last, and used the pass-through setting in the driver to inhibit the cut command but that seems to not work either as the java print job is rendering such text as an image.
I've tried the official Zebra driver as well as using the NiceLabel zebra driver too in the hope that they may have more "Custom Commands" options in the settings but nothing has yet come to light.
After we had the same issues for several weeks and neither the vendor nor google nor Zebra's own support came up with a FULL working solution, we've worked out the following EASY 5 step solution for this (apparently pretty common) Zebra Cutter issue/problem:
Step 1:
Set Cutter-Mode to Tear-Off in the settings.
This will disable the auto-cutting after every single page.
Step 2: Go to Customer-Commands in the settings dialog (Allows ZPL coding).
Step 3: Set the first drop-down to "DOCUMENT".
Step 4: Set the Start-Section to "TEXT" and paste in
^XA^MMD^XZ^XA^JUS^XZ
MMD enables PAUSE-Mode. The JK command is only available in Pause-Mode and many Zebra printers do not support the much easier command CN (Cut-Now).
JUS saves the setting to the printer.
Step 5: Set the End-Section to "ANALYZED TEXT" and paste in
˜JK˜PS
JK sets the cut command to the end of the document, PS disables the pause mode (and thus starts printing immediately). When everything looks as described above, hit "APPLY" and your Zebra printer will automatically cut after the end of each document you send to it. You just send your PDF using sumatra or whatever you prefer. The cutter handling is now automatically done by the printer settings.
Alternatively, if you want to do this programmaticaly, use the START and END codes at the corresponding positions in your ZPL code instead. Note that ˜CMDs cannot be send in combination with ^CMDs, thats why there's no XA...XZ block to reset any settings (which is not necessary in this scenario as it only affects the print session and PS turns the pause mode back to OFF).
I had similar concern but as the print server was CUPS, I wasn't able to use Windows drivers and utilities (settings dialog). So basically, I did the following:
On the printer, set Cutter mode. This will cut after each printed label.
In my Java code, thanks to Apache PDFBox lib, open the PDF and for each page, render it as a monochrome BufferedImage, get bytes array from it, and get its hex representation.
Write a few ZPL commands to download hex as graphic data, and add the ^XB command before the ^XZ one, in order to prevent a cut here, except for the last page, so that there is a cut only at the end of the document.
Send the generated ZPL code to the printer. In my case, I send it as a raw document through IPP, using application/vnd.cups-raw as mime-type, thanks to the great lib ipp-client-kotlin, but it is also possible to use Java native printing API with bytes.
Below in a snippet of Java code, for demo purpose:
public void printPdfStream(InputStream pdfStream) throws IOException {
try (PDDocument pdDocument = PDDocument.load(pdfStream)) {
PDFRenderer pdfRenderer = new PDFRenderer(pdDocument);
StringBuilder builder = new StringBuilder();
for (int pageIndex = 0; pageIndex < pdDocument.getNumberOfPages(); pageIndex++) {
boolean isLastPage = pageIndex == pdDocument.getNumberOfPages() - 1;
BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(pageIndex, 300, ImageType.BINARY);
byte[] data = ((DataBufferByte) bufferedImage.getData().getDataBuffer()).getData();
int length = data.length;
// Invert bytes
for (int i = 0; i < length; i++) {
data[i] ^= 0xFF;
}
builder.append("~DGR:label,").append(length).append(",").append(length / bufferedImage.getHeight())
.append(",").append(Hex.getString(data));
builder.append("^XA");
builder.append("^FO0,0");
builder.append("^XGR:label,1,1");
builder.append("^FS");
if (!isLastPage) {
builder.append("^XB");
}
builder.append("^XZ");
}
IppPrinter ippPrinter = new IppPrinter("ipp://printserver/printers/myprinter");
ippPrinter.printJob(new ByteArrayInputStream(builder.toString().getBytes()),
documentFormat("application/vnd.cups-raw"));
}
}
Important: hex data can (and should) be compressed, as mentioned in ZPL Programming Guide, section Alternative Data Compression Scheme for ~DG and ~DB Commands. Depending on the PDF content, it may drastically reduce the data size (by a factor 10 in my case!).
Note that Zebra's support provides a few more alternatives in order to controller the cutter, but this one worked immediately.
Zebra Automatic Cut - Found another solution.
Create a file with the name: Delayed Cut Settings.txt
Insert the following code: ^XA^MMC,N^XZ
Send it to the printer
After you do the 3 steps above, all the documents you send to the printer will be cut automatically.
(To disable that function send again the 'Delayed Cut Setting.txt' with the following code:^XA^MMD^XZ )
The first document you send to the printer, you need to ADD (just once) the command ^MMC,N before the ^XZ
My EXAMPLE TXT:
^XA
^FX Top section with logo, name and address.
^CF0,60
^FO50,50^GB100,100,100^FS
^FO75,75^FR^GB100,100,100^FS
^FO93,93^GB40,40,40^FS
^FO220,50^FDIntershipping, Inc.^FS
^CF0,30
^FO220,115^FD1000 Shipping Lane^FS
^FO220,155^FDShelbyville TN 38102^FS
^FO220,195^FDUnited States (USA)^FS
^FO50,250^GB700,3,3^FS
^FX Second section with recipient address and permit information.
^CFA,30
^FO50,300^FDJohn Doe^FS
^FO50,340^FD100 Main Street^FS
^FO50,380^FDSpringfield TN 39021^FS
^FO50,420^FDUnited States (USA)^FS
^CFA,15
^FO600,300^GB150,150,3^FS
^FO638,340^FDPermit^FS
^FO638,390^FD123456^FS
^FO50,500^GB700,3,3^FS
^FX Third section with bar code.
^BY5,2,270
^FO100,550^BC^FD12345678^FS
^FX Fourth section (the two boxes on the bottom).
^FO50,900^GB700,250,3^FS
^FO400,900^GB3,250,3^FS
^CF0,40
^FO100,960^FDCtr. X34B-1^FS
^FO100,1010^FDREF1 F00B47^FS
^FO100,1060^FDREF2 BL4H8^FS
^CF0,190
^FO470,955^FDCA^FS
^MMC,N
^XZ

.NET/MVC4/Jquery Mobile/Knockout/Chrome/iPhone extra # character in URL

Okay, if I could offer a bounty for this I would - I offer virtual karma.
As mentioned in the title I have an .NET/MVC4/Jquery Mobile/Knockout website. On the index page there is a button
<button data-bind="click: getResults" data-theme="f">Search</button>
which calls a javascript function
$.mobile.navigate("/results?option1=a&option2=b", { transition: amw.transitions.slide });
This works great on all browsers and devices except Chrome/iPhone. As far as I can tell the version of Chrome or iOS does not matter. The resulting URL in the address bar is
iPhone/Chrome: http://www.mywebsite.com/#/results?option1=a&option2=b
Other Devices: http://www.mywebsite.com/results?option1=a&option2=b
I have put alerts throughout jQuery mobile to try and figure out what is going on (if someone knows a way to debug chrome on iOS let me know) and I cannot see where the extra # is being added.
This may not seem like a big deal but the url ends up being passed on to a downstream service that really does not like the extra #.
I can put in a hack at the call to the service to strip out the # but I would really like to figure out what is happening.
The only suspect line I can find in jQuery mobile (1.3.0) is line #2298
// if the hash is included in the data make sure the shape
// is consistent for comparison
if( data.hash && data.hash.indexOf( "#" ) === -1) {
data.hash = "#" + data.hash;
}
But I am not sure what this does or why it would occour only on Chrome/iPhone.
so StackOverflow people - what is going on?
Thanks.

"document" in mozilla extension js modules?

I am building Firefox extension, that creates single XMPP chat connection, that can be accessed from all tabs and windows, so I figured, that only way to to this, is to create connection in javascript module and include it on every browser window. Correct me if I am wrong...
EDIT: I am building traditional extension with xul overlays, not using sdk, and talking about those modules: https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules
So I copied Strophe.js into js module. Strophe.js uses code like this:
/*_Private_ function that creates a dummy XML DOM document to serve as
* an element and text node generator.
*/
[---]
if (document.implementation.createDocument === undefined) {
doc = this._getIEXmlDom();
doc.appendChild(doc.createElement('strophe'));
} else {
doc = document.implementation
.createDocument('jabber:client', 'strophe', null);
}
and later uses doc.createElement() to create xml(or html?) nodes.
All worked fine, but in module I got error "Error: ReferenceError: document is not defined".
How to get around this?
(Larger piece of exact code: http://pastebin.com/R64gYiKC )
Use the hiddenDOMwindow
Cu.import("resource://gre/modules/Services.jsm");
var doc = Services.appShell.hiddenDOMWindow.document;
It sounds like you might not be correctly attaching your content script to the worker page. Make sure that you're using something like tabs.attach() to attach one or more content scripts to the worker page (see documentation here).
Otherwise you may need to wait for the DOM to load, waiting for the entire page to load
window.onload = function ()
{
Javascript code goes here
}
Should take at least diagnose that issue (even if the above isn't the best method to use in production). But if I had to wager, I'd say that you're not attaching the content script.

Developing a Firefox plugin/addon that invokes "Save As" from FF's own set of functions

I have a basic FF addon that polls for something in the DOM of the page in window.document. When it sees it, it is supposed to save the page. That's the hard part. I don't want to replicate the functionality of "save complete" I just want to call the pre-existing functionality from the plugin/addon at the right moment.
Is this an XPCom thing? Or is it pure JavaScript via the relevant APIs ?
iMacros for Firefox can invoke Save-as (without popping the associated dialog), but I can't see how.
Can anyone advise as to how to call deeper Firefox functions like this?
Thanks, - Paul
PS - I really love Mozilla Archive Format, with MHT and Faithful Save but I think it is replicating functionality again. My alternative is to invoke it's function, but that's as opaque to me as the firefox native one.
You can use nsIWebBrowserPersist.saveDocument() for this:
var persist = Cc["#mozilla.org/embedding/browser/nsWebBrowserPersist;1"].
createInstance(Ci.nsIWebBrowserPersist);
var localPath = Cc["#mozilla.org/file/local;1"].
createInstance(Ci.nsILocalFile);
localPath.initWithPath(pathToLocalDirectory);
var localFile = localPath.clone();
localFile.append("mylocalfile.html");
persist.saveDocument(document, localFile, localPath, null, 0, 0);
The key is the third parameter which specifies where the linked URIs should be stored. See http://mxr.mozilla.org/mozilla2.0/source/embedding/components/webbrowserpersist/public/nsIWebBrowserPersist.idl#256 for complete documentation.

Resources