Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Android: Fix title in Webview Javascript confirm() and alert() dialogs

Normally the alert/confirm dialog prompts have a title, but it doesn't reflect the actual title of the webpage you're viewing.

This may be somewhat annoying or confusing to your users, and thankfully it's an easy fix!

image

What you need to do is configure a custom WebChromeClient on your WebView. This allows you to tweak the styling and behaviour of the WebView components.

m_webview.setWebChromeClient(new JsPopupWebViewChrome());

private class JsPopupWebViewChrome extends WebChromeClient {
@Override
public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
AlertDialog.Builder b = new AlertDialog.Builder(view.getContext())
.setTitle(view.getTitle())
.setMessage(message)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
})
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
});

b.show();

// Indicate that we're handling this manually
return true;
}
}

All of the magic happens in JsPopupWebViewChrome's onJsConfirm() method. You can apply a similar method to make this work with alert() prompts by overriding onJsAlert().

image http://24.media.tumblr.com/tumblr_ltcgdakccJ1qanfdoo1_500.jpg

Android: WebView.addJavascriptInterface() crash workaround for Gingerbread 2.3.x

For a while I thought this was just bad implementation on my part. How could I get it so wrong? I mean, I'm literally just copy-pasting the example from the documentation and it's STILL not working!

Normally, you'd just call this and expect it to work:

m_webview.getSettings().setJavaScriptEnabled(true);
m_webview.addJavascriptInterface(new JSInterface(), "Android");

And normally you'd be right, except on Gingerbread. When you trigger some JS calls to Android 2.3, you'll get this:

JNI WARNING: jarray 0xb5d256f0 points to non-array object (Ljava/lang/String;)
"WebViewCoreThread" prio=5 tid=8 NATIVE
  | group="main" sCount=0 dsCount=0 obj=0xb5cfc348 self=0x8234e98
  | sysTid=2023 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=136531904
  at android.webkit.WebViewCore.nativeTouchUp(Native Method)
  at android.webkit.WebViewCore.nativeTouchUp(Native Method)
  at android.webkit.WebViewCore.access$3300(WebViewCore.java:53)
  at android.webkit.WebViewCore$EventHub$1.handleMessage(WebViewCore.java:1162)
  at android.os.Handler.dispatchMessage(Handler.java:99)
  at android.os.Looper.loop(Looper.java:130)
  at android.webkit.WebViewCore$WebCoreThread.run(WebViewCore.java:633)
  at java.lang.Thread.run(Thread.java:1019)

VM aborting

I ain't done nothing wrong here! Same code works perfectly on other versions of Android.

i74p01uddwr4yldjdh

Well, it turns out that this bug has existed since December 2010 "Issue 12987 - android - Javascript to Java Bridge Throws Exception", and even after 3 years developers still have to jump through hoops to get JavaScript bridging working on 2.3 devices.

image

Gingerbread still holds up to 30% of all device market share on the Play Store at time of writing.

The solution

I'm not gonna lie, this is only a half-baked solution but AWESOME and it's the best I can find so far. It's a method first discovered (or published) by Jason Shah of PhoneGap, then tweaked by Mr S (StackOverflow) to detect multiple versions of Gingerbread.

Unfortunately, there are a few flaws with his implementation which I've taken upon to fix (red ones are still unresolved)

  • Not synchronous, so we can't return values between JS/Java (without callbacks) Fixed 17/9/13
  • Unable to access interface from iframes
  • Required each methods in JSInterface to tokenize a single String argument to accommodate for lack of bridging support
  • Required you to manually map out all methods in the interface
  • Issues with commas/double quotes in strings breaking JS
  • String separator is cumbersome in case data had break string in it
  • It wasn't clear on how to change the interface name

I then took this code and modified it so most of the issues have been ironed out (to a degree).

I wasn't too keen on subclassing the WebView, so here's the helper function. (Don't worry, all the code will be made available for easy copy-pasting in GitHub along with more detailed comments).

private WebView m_webview = null;
private boolean javascriptInterfaceBroken = false;

/**
* @see http://twigstechtips.blogspot.com.au/2013/09/android-webviewaddjavascriptinterface.html
*/
protected void fixWebViewJSInterface(WebView webview, Object jsInterface, String jsInterfaceName, String jsSignature) {
// Gingerbread specific code
if (Build.VERSION.RELEASE.startsWith("2.3")) {
javascriptInterfaceBroken = true;
}
// Everything else is fine
else {
webview.addJavascriptInterface(jsInterface, jsInterfaceName);
}

webview.setWebViewClient(new GingerbreadWebViewClient(jsInterface, jsInterfaceName, jsSignature));
webview.setWebChromeClient(new GingerbreadWebViewChrome(jsInterface, jsSignature));
}

The function fixWebViewJSInterface() simply initiates the WebView with the right implementation depending on the Android build version it's running on.

So replace your addJavascriptInterface() call:

m_webview.addJavascriptInterface(new JSInterface(), "Android");

With the fix:

fixWebViewJSInterface(webview, new JSInterface(), "Android", "_gbjsfix:");

GingerbreadWebViewClient and GingerbreadWebViewChrome contains pretty much all the workaround logic, so prepare yourself for a lengthy snippet!

How it works

Normally, JavaScript in the WebView is able to call Android functions via the interface name "Android" or whatever name we gave it. For example:

Android.showToast("Hello! Is it me you're looking for?");

At the fixWebViewJSInterface() level, the fix is relatively simple. Anything other than Gingerbread 2.3 will use the normal JavaScript interface implementation addJavascriptInterface().

However anyone on Android 2.3 we'll have to treat a little differently, but be glad to know that the JS code itself is (mostly) the same. We DON'T actually set the interface, but instead mark the interface as broken and let GingerbreadWebViewClient/GingerbreadWebViewChrome handle the rest as it'll:

  • Wait until the page has finished loading
  • Generate JS code based off your JSInterface class methods
  • Inject our own "Android" interface object into the page
  • Call android_init() at the end of it all (even on non-Gingerbread Android)

GingerbreadWebViewClient is responsible for the JS code injection and re-injection into the broken WebView.

Regarding the JS code generated:

  • Declares an "Android" object so we don't have to change the JS code we write in the WebView
  • Replicate the method names into the "Android" interface object
  • All the methods will wrap Android._gbFix()
  • _gbFix() is a function which seals the function arguments (and some meta data) into JSON
  • The JS signature is appended to the generated JSON and passed to GingerbreadWebViewChrome via prompt()
  • prompt() will wait for a response, thus making it a synchronous call

Calls by prompt() from the WebView's JS to the Android interface will trigger these events within GingerbreadWebViewChrome:

  • onJsPrompt() picks up the prompt() call and checks the message for the JS signature
  • Decode the meta data from the JSON bubble-wrap
  • Attempt to map the method back to the JSInterface class we've defined and invoke it

 

Well, I promised you a lengthy snippet. Here it is!

private class GingerbreadWebViewClient extends WebViewClient {
private Object jsInterface;
private String jsInterfaceName;
private String jsSignature;

public GingerbreadWebViewClient(Object jsInterface, String jsInterfaceName, String jsSignature) {
this.jsInterface = jsInterface;
this.jsInterfaceName = jsInterfaceName;
this.jsSignature = jsSignature;
}


@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);

if (javascriptInterfaceBroken) {
StringBuilder gbjs = new StringBuilder();

gbjs.append("javascript: ");
gbjs.append(generateJS());

view.loadUrl(gbjs.toString());
}

// Initialise the page
view.loadUrl("javascript: android_init();");
}


/**
* What this JS wrapper function does is convert all the arguments to strings,
* in JSON format before sending it to Android in the form of a prompt() alert.
*
* JSON data is returned by Android and unwrapped as the result.
*/
public String generateJS() {
StringBuilder gbjs = new StringBuilder();

if (javascriptInterfaceBroken) {
StringBuilder sb;

gbjs.append("var "); gbjs.append(jsInterfaceName); gbjs.append(" = { " +
" _gbFix: function(fxname, xargs) {" +
" var args = new Array();" +
" for (var i = 0; i < xargs.length; i++) {" +
" args.push(xargs[i].toString());" +
" };" +
" var data = { name: fxname, len: args.length, args: args };" +
" var json = JSON.stringify(data);" +
" var res = prompt('"); gbjs.append(jsSignature); gbjs.append("' + json);" +
" return JSON.parse(res)['result'];" +
" }" +
"};");

// Build methods for each method in the JSInterface class.
for (Method m : jsInterface.getClass().getMethods()) {
sb = new StringBuilder();

// Output = "Android.showToast = function() { return this._gbFix('showToast', arguments); };"
sb.append(jsInterfaceName);
sb.append(".");
sb.append(m.getName());
sb.append(" = function() { return this._gbFix('");
sb.append(m.getName());
sb.append("', arguments); };");

gbjs.append(sb);
}
}

return gbjs.toString();
}
}


private class GingerbreadWebViewChrome extends WebChromeClient {
private Object jsInterface;
private String jsSignature;


public GingerbreadWebViewChrome(Object jsInterface, String jsSignature) {
this.jsInterface = jsInterface;
this.jsSignature = jsSignature;
}


@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
if (!javascriptInterfaceBroken || TextUtils.isEmpty(message) || !message.startsWith(jsSignature)) {
return false;
}

// We've hit some code through _gbFix()
JSONObject jsonData;
String functionName;
String encodedData;

try {
encodedData = message.substring(jsSignature.length());
jsonData = new JSONObject(encodedData);
encodedData = null; // no longer needed, clear memory
functionName = jsonData.getString("name");

for (Method m : jsInterface.getClass().getMethods()) {
if (m.getName().equals(functionName)) {
JSONArray jsonArgs = jsonData.getJSONArray("args");
Object[] args = new Object[jsonArgs.length()];

for (int i = 0; i < jsonArgs.length(); i++) {
args[i] = jsonArgs.get(i);
}

Object ret = m.invoke(jsInterface, args);
JSONObject res = new JSONObject();
res.put("result", ret);
result.confirm(res.toString());
return true;
}
}

// No matching method name found, should throw an exception.
throw new RuntimeException("shouldOverrideUrlLoading: Could not find method '" + functionName + "()'.");
}
catch (IllegalArgumentException e) {
Log.e("GingerbreadWebViewClient", "shouldOverrideUrlLoading: Please ensure your JSInterface methods only have String as parameters.");
throw new RuntimeException(e);
}
catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
catch (JSONException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}

If you're using a custom WebViewClient and/or WebChromeClient, simply change the subclasses for your one or merge the code somehow. I'll assume you're capable enough as no support will be given here.

Zmoe2S2
Maybe this guy's a little TOO capable...

Things you should be aware of

android_init()

Due to the delay between page load and JS injection, you have to assume that the JS interface is NOT available to you until android_init() has been called. Because of this, you must always declare android_init(), even if it's not used.

If you have any code in $(document).ready() or onload() which uses the Android interface, you may want to move it into android_init().

I think this is a fairly small trade-off for the convenience this method provides.

JSInterface method parameters

The JavaScript calls can be a mixture of numbers and strings, but all parameters in JSInterface Android class must be of type String.

This could probably be fixed later, but I was short on time and chose to convert all the arguments into strings when invoking the method.

Limitations

  • Not synchronous, so we can't return values between JS/Java (without callbacks) Fixed 17/9/13
  • Unable to access interface from iframes
  • Required each methods in JSInterface to tokenize a single String argument to accommodate for lack of bridging support See android_init() limitation and JSInterface method parameters
  • Required you to manually map out all methods in the interface Now automatic
  • Issues with commas/double quotes in strings breaking JS Fixed with JSON
  • String separator is cumbersome in case data had break string in it Fixed with JSON
  • It wasn't clear on how to change the interface name Now an argument to fixWebViewJSInterface()

Here's the link to the code on GitHub. It includes a few more comments to clarify some points here and there.

That's all folks! I feel like I've jumped through enough hoops for now.

D47Z6

Update

17/9/2013: Rewrote the tutorial so the calls are synchronous! No more messy callbacks, yay!

Sources

Big thanks to Jason Shah for sharing his findings and making this work-around possible.

Blogger.com: Disable country domain redirects

I'm getting annoyed at my web traffic stats being all messed up because the URLs aren't being counted properly.

Popular Pages - Twigs Tech Tips

People browsing from different part of the world are being redirected to their government friendly top level domains (TLD's) and it's just annoying.

This is meant to be the internet, a place where information roams free from the slow red tape of bureaucracy.

Thankfully, there's a quick fix for this and it doesn't involve any unnecessary pain.

2843_0c8f
  • Firstly, log in to your blogger.com admin.
  • Secondly, open up the dashboard for your blog.
  • Click "Template"
  • Click "Edit HTML"
  • Click "Proceed"
  • Select "Expand Widget Templates" at the top.
  • Using your browser, search for </head>
  • Just before that, paste this in:
<script type="text/javascript">
function check_redirect(your_domain) {
if (window.location.host.split('.').pop() != your_domain.split('.').pop()) {
var new_url = window.location.href;
new_url = new_url.replace(window.location.protocol + "//" + window.location.hostname, window.location.protocol + "//" + your_domain + "/ncr");
window.location.href = new_url;
}
}

check_redirect("twigstechtips.blogspot.com.au");
</script>
  • Change the 2nd last line to whatever you want your domain to be. In this case, I want to enforce it so everyone visits the .au one.
  • Click save.
  • Test it out!

Source

Originally I found the information from here, but from inspection it doesn't seem to cover all the domains I have been seeing in the stats such as .co.uk.

I've rewritten it a little so it does the domain detection and replacement better.

Javascript: String starts with snippet

I was surprised to find out that Javascript didn't come with such a function.

It's pretty easy to monkey patch though, it doesn't even need jQuery!

if (typeof String.prototype.startsWith != 'function') {
String.prototype.startsWith = function (input){
return this.substring(0, input.length) === input
};
}

After that you can just use it like any other string function.

var hash = "#someAnchor";

if (hash.startsWith('#img_')) {
$('a[href="' + hash + '"]').trigger('click');
}

SsgD9
Now we've trained Javascript well!

Source

Javascript: Render file size in a human readable format to two decimal places

Displaying the size of files is one thing but formatting them so they're actually understandable by humans, Another.

I've found this useful snippet by inkdeep but corrected the bit/byte units, used a different rounding function and cleaned up the if blocks.

function humanize_filesize(fs) {
if (fs >= 1073741824) { return round_number(fs / 1073741824, 2) + ' GB'; }
if (fs >= 1048576)    { return round_number(fs / 1048576, 2) + ' MB'; }
if (fs >= 1024)       { return round_number(fs / 1024, 0) + ' KB'; }
return fs + ' B';
};

This snippet uses round_numbers() which I've written in another post.

Source

Javascript: Round numbers off to X decimal places

Simple little snippet which I was surprised wasn't part of the Math class.

function round_number(num, dec) {
return Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
}

Source

Javascript: JSON validator

JSON is fine and dandy when it works well, but damned if it's missing a comma or the bloody keywords are quoted in the wrong characters.

I had a problem with some (assumingly) well formed JSON, but it kept puzzled me for hours when a jQuery AJAX post kept silently failing.

Eventually I stumbled upon jsonlint.com, a nifty site that simply validates your JSON and formats it for easy reading.

My example JSON:

{
    'num_votes': 5,
    'up': 4,
    'down': -1
}

Can you spot what's wrong with it?

No? Neither could I... until I got fed up and changed the single quotes with double quotes for the hell of it.

AND IT BLOODY WORKED!

This is the now valid JSON:

{
    "num_votes": 5,
    "up": 4,
    "down": -1
}

FML.

8891
Oh well, back to it!

Javascript: Get function arguments dynamically

Sometimes its handy (during debugging) to see what arguments are being passed to the function.

Within the local scope of the function, the special variable "arguments" will contain the information you need.

Use "arguments.length" to determine how many there are.

[ Source ]

jQuery: Slide/expand to a certain size

The stock animation effects given in jQuery are pretty good for the majority of tasks.

However, if you want to show an element at a given size and then slide it to full expanded view, you'll need to do a little magic.

This was based on a small snippet by Chris Pollock, but I've made it a bit more flexible so it'll work on a wider number of cases.

  • Allows effect to apply on more than 1 element at a time.
  • Size is passed into the setup call to allow for multiple sizes.
  • Original height is saved as $.data() rather than an attribute.
  • Maintain original trigger HTML to allow for easier styling.
  • Trigger element made optional argument. Sizable element is now the trigger if none specified.
  • Able to specify the open/close labels for the trigger element.

Snippet:

You can download the snippet here.

Sample uses:

The single element examples apply to individual elements.

Applying sizeExpand to groups of elements will work best if the element expands itself. If you wish to expand the each element with its own trigger, you'll have to manage that within a loop.

$(document).ready(function() {
// single elements
$('#single-element').sizeExpand('50px');

$('#sized-element').sizeExpand('50px', { 'trigger': '#trigger-element' });

$('#sized-element').sizeExpand('50px', { 'trigger': '#trigger-element', 'open_label': 'Show me the money!', 'close_label': 'I have no money :(' });

// groups of elements
$('div.sized-group').sizeExpand('50px');
});

[ Source ]

A Brief, Incomplete, and Mostly Wrong History of Programming Languages

An absolute cracker of a nerdy post by James Iry, author of One Div Zero.

See it here: A Brief, Incomplete, and Mostly Wrong History of Programming Languages

Couldn't agree more with 1996-2001 =P

jQuery: Fade and slide at the same time

Chaining functions is really handy, but when it comes to animation, its a bit annoying because it'll perform them in order.

To get fade and slide at the same time, use animate().

$('#element').animate({ opacity: 'toggle', height: 'toggle' }, "slow", callback_function);

The speed and callback functions are optional.

[ Source ]

Javascript: Print this page

To trigger the "print page" dialog, simply use the following line:

window.print();

Firebug: Logging JavaScript variables and output

Firebug adds a handy global variable called "console" to your page, which you can use to print stuff into the console window.

var body = $('body');
console.debug(body);

In the console window you can browse the variable you've printed.

image

Clicking on the object will take you to the DOM tab, which will allow you to explore the information contained within the variable.

image

There are a number of other functions such as console.dir() which displays all the properties of the object and console.trace() which shows you the stack trace.

You can see the full list of functions here.

[ Source ]

JavaScript: Call a string as a function with arguments

Man, I sure had trouble giving a proper name to this post.

// Convert string to a function reference
var strFun = "myFunctionName";
var func = eval(strFun);

if (typeof func == 'function') {
// call it
func(param1, param2);
}

The string "strFun" is converted to a function "func". If func() checks out to be a valid function using typeof to check if the function exists, then we just call it with the arguments it needs.

jQuery: Filter out non-printable keypress events

Its pretty handy to listen in for keydown, keyup and keypress events, but it also listens in for a bunch of stuff that, most of the time, we're really not interested in (such as ESC, Tab, F1-F12, backspace, CTRL+C, ALT+Tab, etc).

To filter out those extra triggers we don't need, add the following check at the start of your event handler:

// Filter out special keys
if (e.charCode && !e.originalEvent.altKey && !e.originalEvent.ctrlKey) {
alert('OK');
}
else {
alert('DUD');
}

"e.charCode" will excluse the majority of the non printable keypresses. If you want to keep a specific key (such as backspace, which is useful for searching), then use the following snippet to check for the corresponding key code you want.

var code = (e.keyCode || e.which);

This ensures its compatible with more browsers.

jQuery: Window height given wrong value in Opera

After some messing around with jQuery, Opera and CSS, I figured it wasn't my fault the element wasn't being centered in the middle of the screen.

The reason being that as of Opera 9.5, they relocated the body height of the document to another place, so jQuery retrieves the wrong size when you call $(window).height().

A simple one line fix would to retrieve the correct height would be:

// fix a jQuery/Opera bug with determining the window height
var h = $.browser.opera && $.browser.version > "9.5" &&
$.fn.jquery <= "1.2.6" ?
document.documentElement["clientHeight"] :
$(window).height();

[ Source ]

Internet Explorer 6: No String.trim() support

Its not exactly a well kept secret that web developers loathe IE6, but I never expected to leave out a simple function such as String.trim().

A simple test script such as this would cause an error.

alert("     hello world    ".trim());

image
An unwelcome surprise.

Luckily, theres an easy fix for that! Simply paste this code near the top before any trim() calls are made.

if (!('trim' in String.prototype)) {
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g,""); };
}

image 
Yay its working now!

[ Source ]

JS Error: "Expected identifier, string or number" but only on Internet Explorer

I got some cryptic errors on Internet Explorer when the document was trying to load. Took me a few hours to hunt this bastard down!

image

Hmm ok, so I took a look at line 269 of the HTML and it had nothing. At first I thought it was a JQuery bug. Nope it wasn't.

After taking a look at the error details, I got this:

image
Err, wtf?

Bloody hell! Does it hurt to be a little more descriptive?

After enabling the script debugger (instructions), I found that the errors were caused by defining objects with a trailing comma at the end of the last field.

image
A snippet of the "ajaxupload_3_6.js"

Removing the "," at the end of the "onError" line would fix the issues. Seems that IE has an issue parsing it and decides to stop executing scripts on the page altogether.

JS: How to share links on Facebook from your site

Ever noticed some sites have this?

image

It allows you to post a link to their content on your Facebook profile. One way of doing it is this is to:

First, create a link with the corresponding details.

<a name="fb_share" type="icon_link" share_url="http://yoursite.com/id=45">Share this to my Facebook amigos</a>

Then import the JavaScript from Facebook which renders the button and creates a popup for sharing.

<script src="http://static.ak.fbcdn.net/connect.php/js/FB.Share" type="text/javascript"></script>

Whalla, you should now have a share on Facebook button.

Facebook also supplies a code generator in case you don't know enough HTML ...

Title and Description

You may find that the title and description in the summary may not match with what you want.

Luckily, you can specify the default values using meta tags on the page you're linking to.

Be sure to set these to ensure that Facebook pulls the right details.

Examples:

<meta name="title" content="Smith hails 'unique' Wable legacy" />
<meta name="description" content="John Smith claims beautiful football is the main legacy of Akhil Wable's decade at the club. " />
<link rel="image_src" href="http://www.onjd.com/design05/images/PH2/WableAFC205.jpg" />

*edit 18/01/2010*

  • Added Title & Description section

[ Source, Metatag examples ]

JS Syntax Highlighter

Good software that configurable and does exactly what you want is often hard to come by. Since I've started this blog, I've always wanted a good syntax highlighter that looks nice but was flexible enough to support a large number of languages. I've tried quite a few, but each had their own annoying little quirks.

Lucky for me, a smart chap called Alex Gorbatchev has created an awesome open source syntax highlighter in Javascript. It simply searches through for all "pre" tags with a specific classname and applies the highlighting once your page is loaded.

To use it, import the following files into your HTML file within the "head" tag.

<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>

If you do not wish to use the latest version, replace "current" with the specific version you want. Alex has been nice enough to host the files for us and make it available for public use.

The brush files extend the syntax highlighter functionality to include other languages such as C#, JS, PHP or C++. Be sure to import the files you need.

The following example imports SQL and C++ brushes for use.

<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'/>

If you want to know what other brushes are available, they are listed here.

To configure Syntax Highlighter, you can do so by using the following:

<script type='text/javascript'>
// Makes Syntax Highlighting work for blogger.com sites
SyntaxHighlighter.config.bloggerMode = true;

// Customize tab size
SyntaxHighlighter.defaults['tab-size'] = 2;
// ... more options

// This applies the highlighting
SyntaxHighlighter.all();
</script>

For more configuration options, see here.

When you wish to apply the highlighting onto a specific block of code, place the code within a "pre" tag and apply a CSS class "brush: php" (if you're displaying PHP). Find the right brush alias here.

<pre class="brush: cpp;">
HWND getDesktopHandle();

// Provides visual clues on the state of the application.
void UpdateUI() {
  HMENU menu = GetMenu(m_hWnd);
  LPHIDEDESKTOPINIINFO info = m_map.open();

  CheckMenuItem(menu, ID_MENU_ENABLED, MF_BYCOMMAND | (info->hExplorerLib ? MF_CHECKED : MF_UNCHECKED));
  CheckMenuItem(menu, ID_MENU_STARTUPWITHWINDOWS, MF_BYCOMMAND | (IsAutoStartup() ? MF_CHECKED : MF_UNCHECKED));

  m_map.close(info);
}
</pre>

Its also important to note that alot of WYSIWYG blog editors are not very "pre" tag friendly. Fortunately, this is configurable in Syntax Highlighter by changing the "tagName" option to something else like "div".

There you have it! Now you have fully functional, very pretty syntax highlighting.

[ Sources ]

 
Copyright © Twig's Tech Tips
Theme by BloggerThemes & TopWPThemes Sponsored by iBlogtoBlog