Local Storage Exposed to Users - html

Are the values of items stored using the localStorage API viewable by users? Just like cookies?

Safari and Chrome's web inspector allows inspection of that data, yes. I'm not sure how other browsers handle it, but it's certainly not something you can depend on not being edited.

You can easily load the items to be displayed to users.
Just loop through all the items in local storage using Javascript as the page loads...
<body>
<script language="JavaScript" type="text/javascript">
var item = "";//array to hold string values for each key value
var key ="";//array to hold string values for each key name
for (i=0;i < localStorage.length;i++) {
var count = 0;
if (key != "" | key != null) { //or matches what you're looking for
item[count] = localStorage.getItem(key);
key(i) = localStorage.key(i);
count += 1;
}
}
function load_table()
{
if (item == "" || item == " " || item == null) {
document.write("<div id=\"list_table\" style=\"display: block;\">");
document.write("<h3>You have no stored items.</h3>");
document.write("</div>");
}
else {
document.write("<div id=\"list_table\" style=\"display: block;\">");
document.write("<h3>Stored Items</h3>");
document.write("<table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">");
for (i=0;i < item.length;i++) {
document.write("<tr><td width=\"33%\" valign=\"top\">"+item(i)+"</td>");
document.write("<td width=\"67%\" valign=\"top\" style=\"padding-left: 0px; text-transform: capitalize;\">"+key(i)+"</td></tr>");
}
}
document.write("</table>");
document.write("</div> <!-- end list_table div -->");
} // end if (item != "")
} // end load_table
</script>
In the html, you stick a div that can be shown or hidden, in an appropriate place.
<div id="items_table" style="display: none;">
<script language="JavaScript" type="text/javascript">
//alert("calling load_table");
load_table();
//alert("DONE calling load_table");
</script>
</div>
If they click a link, you can then display items_table that is populated during page load, and hidden. So long as you don't have thousands of items to load, it loads quickly.
I can dig up a link to toggling the display between block and none for the style display property if you like.

Related

Is it possible to track Active Cell change in Google Sheet Sidebar

I'm writing a sidebar which displays additional information based on selected row/cell by user. It's rendering fine on sidebar open, but if the user changes active cell, I need to update content.
Apparently, I can add a "refresh" button in sidebar, but I really want to avoid clicking "refresh" every time. Putting it on timer also isn't very good cause will just spam with unnecessary requests to sheet app.
Has anyone ever did something similar and that approach did you use?
Maybe it's possible somehow to get event about user changing active cell into the sidebar javascript code?
I've put together a prototype of a sidebar that collects all the cell the user clicks in. Starting with an onSelectionChange() trigger to record the cells the user clicks in and recording them to PropertyService Document Properties, when the user moves the mouse over the sidebar the cells that were selected will show up.
First we have a simple Sidedbar
HTML_Sidebar.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<textarea id="textArea" rows="10" cols="35" onmouseenter="onMouseEnter()">
</textarea>
<?!= include('JS_Sidebar'); ?>
</body>
</html>
Next we have the client side code
JS_Sidebar.html
<script>
function onMouseEnter() {
try {
google.script.run.withSuccessHandler(
function(selections) {
let textArea = document.getElementById("textArea");
let text = textArea.value.trim();
selections.forEach( cell => {
text = text + "You clicked cell "+cell+"\n";
}
);
textArea.value = text;
}
).getLatestSelections();
}
catch(err) {
alert(err);
}
}
</script>
Now for all the server side code.
Code.gs
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
function showSidebar() {
var html = HtmlService.createTemplateFromFile("HTML_Sidebar");
html = html.evaluate();
SpreadsheetApp.getUi().showSidebar(html);
}
function onSelectionChange(event) {
try {
// event = {"range":{"columnEnd":3,"columnStart":3,"rowEnd":1,"rowStart":1},"authMode":"LIMITED","source":{},"user":
// {"email":"xxxxxxxxxx#gmail.com","nickname":"xxxxxxxxx"}}
let properties = PropertiesService.getDocumentProperties();
let property = properties.getProperty("_Selections");
if( !property ) property = "";
property = property + JSON.stringify(event) + "\n";
properties.setProperty("_Selections",property);
}
catch(err) {
Logger.log("Error in onSelectionChange: "+err)
}
}
function getLatestSelections() {
try {
let properties = PropertiesService.getDocumentProperties();
let property = properties.getProperty("_Selections");
if( !property ) property = "";
properties.deleteProperty("_Selections");
properties = property.split("\n");
properties.pop(); // remove the last \n element
return properties.map( property => {
let cell = JSON.parse(property);
return getRangeA1(cell.range.rowStart,cell.range.columnStart);
}
);
}
catch(err) {
Logger.log("Error in getLatestSelections: "+err)
}
}
function getRangeA1(row,col) {
try {
let colNum = col;
let colName = "";
let modulo = 0;
while( colNum > 0 ) {
modulo = (colNum - 1) % 26;
colName = String.fromCharCode(65 + modulo) + colName;
colNum = Math.floor((colNum - modulo) / 26);
}
colName = colName+(row);
return colName;
}
catch(err) {
throw "Error in getRangeA1: "+err;
}
}
Screen shot
I understand that you want to record when the active cells change on a Sheet, and you want to do it without resorting to timers or buttons. If my understanding of your scenario is correct, then your best bet is using onSelectionChange triggers.
You can introduce an onSelectionChange trigger in your script to execute a refresh every time that the user changes the active cell. Leave a comment below if you have questions about this approach.

Why does this Javascript function rewrite the innerHTML of one div but not the other?

I'm using NodeJS to query a MySQL database for a single entry of a journal, but the results aren't going to both of the assigned divs. I have an iFrame in my center column, dedicated to two divs (one hidden at any given time). One div is a read-only page for the journal entry, and the other one contains a TinyMCE rich-text editor. I have buttons in left column to switch between the views.
The rich-text editor loads properly on initial load of page, but doesn't update as I navigate with the calendar; the read-only innerHTML does update properly as I navigate.
calDt[] is an array that holds dates. calDt[0] is the active date, while calDt[1] holds a dummy date used for navigating the calendar without changing the entry.
app.js:
app.get('/getdata/:dateday', (req, res) => {
let sql = `SELECT entry FROM main where dateID ='${req.params.dateday}'`
let query = db.query(sql, (err, results) => {
if(err) {
throw err
}
res.send(JSON.stringify(results));
})
})
middle-left.ejs
<button style= "height:22px"; type="button" onclick="readDivHere()">Lock</button>
<button style= "height:22px"; type="button" onclick="editDivHere()">Edit</button></div>
<script> // the Lock button brings us back to the completed entry in the middle stuff
function readDivHere() {
document.getElementById('frame1').contentWindow.readDivHere();
document.getElementById('frame1').scrolling = "yes";
}
</script>
<script> // the Edit button will bring tinymce rich-text editor to the middle stuff
function editDivHere() {
document.getElementById('frame1').contentWindow.editDivHere();
document.getElementById('frame1').scrolling = "no";
}
</script>
middle-center.ejs
<iframe id="frame1" class="entryon" src="" frameborder="0px"></iframe>
<script>
document.getElementById("frame1").src = "iframe";
</script>
iframe.ejs
<div id="readDiv" class="here" style="display: block; background: white; padding-top: 0px; padding-left: 10px; padding-right: 8px; min-height: 810px; width: 967px;"><%- include ('entry'); %></div>
<div id="editDiv" class="here" style="display: none; padding: 0px;" ><%- include ('editPage'); %></div>
<script> //function that switches from rich-text editor back to real entry
function readDivHere() { // here we run a function to update text of read-only entry
document.getElementById("readDiv").style.display="block";
document.getElementById("editDiv").style.display="none";
}
</script>
<script> //function that switches from read-only entry to rich-text editor
function editDivHere() {
document.getElementById("readDiv").style.display="none";
document.getElementById("editDiv").style.display="block";
}
</script>
entry.ejs
<div id="readOnlyEntry"></div>
<script>
// load the active entry into the middle column for proper reading
function loadEntry(p) {
var x = parent.calDt[1].getFullYear();
var y = parent.calDt[1].getMonth();
y = y + 1;
if (y < 10) {
y = "0" + y;
};
if (p < 10) {
p = "0" + p;
}
var newDate = x + "" + y + "" + p; // p is a date formatted like 20210808
            var xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = function() {
                const text = this.responseText;
                const obj = JSON.parse(text);
document.getElementById("readOnlyEntry").innerHTML = obj[0].entry;
document.getElementById("richTextEd").innerHTML = obj[0].entry; // doesn't work!
            }
xhttp.open("GET", "../getdata/" + newDate, true);
        xhttp.send();
}
</script>
<script>
// rich-text editor populates correctly on load
loadEntry(parent.calDt[0].getDate());
</script>
editPage.ejs
<%- include ('tinymce'); %>
<form method="POST" action="../result" enctype="multipart/form-data">
<textarea name="content" id="richTextEd">Here's the default text.</textarea>
</form>
calendar-clicker.ejs
var p = x.innerHTML; // get the value of the calendar cell text (i.e. day of the month)
p = p.match(/\>(.*)\</)[1];
var d = calDt[1].getFullYear(); // what year is the calendar referencing?
var q = calDt[1].getMonth(); // what month is the calendar referencing?
q = q + 1; // compensate for javascript's weird month offset
calDt[0] = new Date(q + "/" + p + "/" + d); // assign a new global date variable
calDt[1] = calDt[0]; // temporarily reset navigation date to active date
document.getElementById('frame1').contentWindow.loadEntry(p);
Does the failure have to do with assigning the innerHTML to a different .ejs? If I put the form into the same div as the read-only entry, the form still fails to update as I navigate.
Solved it.
In entry.ejs, I replaced...
document.getElementById("richTextEd").innerHTML = obj[0].entry;
with
tinymce.get("richTextEd").setContent(obj[0].entry);
https://www.tiny.cloud/blog/how-to-get-content-and-set-content-in-tinymce/

how to create html table results from JSON data

I have code that uses AJAX and JSON to output a chunk of SQL data when you do a search and I am trying to separate the data some and have it display into an HTML table. At first it was just the SQL data but I put some tags into the innerHTML line to at least visually separate it, however I would really like to be able to put each column into a separate table cell. Any ideas on how to do that would be greatly appreciated. Here is the code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="js/jquery-2.2.2.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<link href="css/bootstrap.min.css" rel="stylesheet">
<title>AJAX Search Example</title>
<script>
function fetch() {
// (A) GET SEARCH TERM
var data = new FormData();
data.append('search', document.getElementById("search").value);
data.append('ajax', 1);
// (B) AJAX SEARCH REQUEST
var xhr = new XMLHttpRequest();
// (CHANGE1) USING ONREADYSTATECHNAGE INSTEAD OF ONLOAD
xhr.onreadystatechange = function (event) {
// (CHANGE2) we will check if ajax process has completed or not it goes from 1,2,3,4 means end.
if(this.readyState == 4){
// (CHANGE2) when ready state comes to 4 we then check what response status was it if it is 200 good else error.
if(this.status == 200){
// (CHANGE3) MOVED ALL YOUR CODE HERE
// (CHANGE4) we need to use responseText instead of response because JSON comes as string that is why we are parsing it to be converted into array
var results = JSON.parse(this.responseText);
//I have added just a measure to check what the out put is you can remove it latter. open dev console to get the result.
console.log(results);
wrapper = document.getElementById("results");
if (results.length > 0) {
wrapper.innerHTML = "";
// (CHANGE5) UPDATED data ref with results
for (i = 0; i < results.length; i++) {
let line = document.createElement("div");
//it is just as simple to create id only it must start with alphabet not number
line.id=`res${[i]}`;
//we created span tag to display price and this is what we will change. on that span we will create a data-price attribute which will hold original price and we will run calculations using that number
//BIG CHANGE
//BIG CHANGE
//since after parsing individual record will be in Js object so we dont need to access them like array results[i]['item']
//we access them with dot notation results[i].item
line.innerHTML = `Category:${results[i].category} - OEM #:${results[i].oemnumber} - Price:$<span data-price='${results[i].price}'>${results[i].price}</span>
select discount >>
%70
%60
%50 100%`;
wrapper.appendChild(line);
}
// (CHANGE6) We moved event listeners here so any newly added elements will be updated.
//get all the links and apply event listener through loop
var links = document.querySelectorAll('a');
for ( ii = 0; ii < links.length; ii++) {
links[ii].addEventListener("click", function(event) {
//capture link value and get number to be converted to percentage
var percentage = event.target.innerText.match(/\d+/)[0]/100;
//capture the data-price which is within same div as anchor link
var pricetarget = event.target.parentElement.querySelector('[data-price]');
//get value of data-price
var actualprice= pricetarget.dataset.price;
//run math and chnage the value on display
pricetarget.innerHTML=(actualprice*percentage).toFixed(2);
});
}
} else { wrapper.innerHTML = "No results found"; }
} else {
//if reponse code is other ethan 200
alert('INTERNET DEAD OR AJAX FAILED ');
}
}
};
// (CHANGE7) We moved open event to end so everything is ready before it fires.
xhr.open('POST', "2-search.php");
xhr.send(data);
return false;
};
</script>
</head>
<body>
<!-- (A) SEARCH FORM -->
<form ID='myForm' onsubmit="return fetch();">
<h1>SEARCH FOR CATALYTIC CONVERTER</h1>
<input type="text" id="search" required/>
<input type="submit" value="Search"/>
</form>
<!-- (B) SEARCH RESULTS -->
<div id="results"></div>
</body>
</html>
Here is where I added the tags to at least visually separate it: "line.innerHTML = `Category:${results[i].category} - OEM #:${results[i].oemnumber} - Price:$${results[i].price}"
What I want to do is have Category, OEM #, and price each in a separate table cell. Thank you for any help offered.
You can simply generate trs inside your for (i = 0; i < results.len.. like you are already doing for divs . So , just use += to append every new tr inside tbody and then append this to your table
Demo Code :
//suppose json look like below :)
var results = [{
"category": "A",
"price": 13,
"oemnumber": "d1A"
}, {
"category": "B",
"price": 15,
"oemnumber": "d1B"
}, {
"category": "C",
"price": 12,
"oemnumber": "d1C"
}]
fetch();
function fetch() {
/* var data = new FormData();
data.append('search', document.getElementById("search").value);
data.append('ajax', 1);
var xhr = new XMLHttpRequest();
// (CHANGE1) USING ONREADYSTATECHNAGE INSTEAD OF ONLOAD
//some codes/..
console.log(results);*/
wrapper = document.getElementById("results");
wrapper.innerHTML = "";
var rows = "";
if (results.length > 0) {
for (i = 0; i < results.length; i++) {
//generate trs
rows += `<tr id=res${[i]}><td>${results[i].category}</td><td>${results[i].oemnumber}</td><td>$<span data-price='${results[i].price}'>${results[i].price}</span>
select discount >>
%70
%60
%50 100%</td></tr>`;
}
wrapper.innerHTML = `<table class="table">
<thead><th>Category</th><th>OEM</th><th>Price</th></thead><tbody>${rows}</tbody></table>`;
//sme other codes,,
}
};
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<div id="results">
</div>

Problems getting SCORM 2004 to do what it's supposed to

Thanks for reading and I hope you can give me a hand with this.
I don't have much experience with SCORM; until now I had always worked in SCORM 1.2 but I have been asked to deliver a project in SCORM 2004. This is for a course which has been built in HTML5 directly in Dreamweaver and I've linked the JS as external files.
WHAT IS SUPPOSED TO HAPPEN:
1) Supposedly I'm storing the lesson location so that when you exit a lesson and open it again, you start off on the page where you left it. Unfortunately, it always starts again from the first page.
2) Supposedly the lesson should not be marking itself as "completed" until you reach the last page of the lesson, but unfortunately it marks itself as "completed" as soon as you've started the lesson.
Following are samples of my code, starting with three HTML samples (first page of the lesson, intermediate pages of the lesson and final page of the lesson), and then the two JS files with my SCORM functions.
1) HTML: first page of the lesson.
<script type="text/javascript" language="javascript" name="mm_scormRTI" src="SCOfunctions.js"></script>
<script language="javascript">
var currentScoPage = scoPage[ i ] ;
SetValue("cmi.location", currentScoPage );
Terminate(); // close out this SCO, we are finished
</script>
<script language="javascript">
Initialize(); // initialize the SCO with the LMS
var currentScoPage = GetValue("cmi.location");
if (currentScoPage != "") {
self.location = currentScoPage;
}else{
currentScoPage = scoPage[0];
}
</script>
</head>
<body onLoad="mm_adlOnload()">
...
2) HTML: intermediate pages of the lesson
<script type="text/javascript" language="javascript" name="mm_scormRTI" src="SCOfunctions.js"></script>
<script language="javascript">
var currentScoPage = scoPage[ i ] ;
SetValue("cmi.location", currentScoPage );
Terminate(); // close out this SCO, we are finished
</script>
</head>
<body onLoad="mm_adlOnload()">
...
3) HTML: final page of the lesson
<script type="text/javascript" language="javascript" name="mm_scormRTI" src="SCOcomplete.js"></script>
<script language="javascript">
var currentScoPage = scoPage[ i ] ;
SetValue("cmi.location", currentScoPage );
Terminate(); // close out this SCO, we are finished
</script>
</head>
<body onLoad="mm_adlOnload()" onUnload="mm_adlOnunload()">
...
4) SCORM: external file "SCOfunctions.js"
function mm_adlOnload()
{
if (mm_adl_API != null)
{
mm_adl_API.Initialize("");
mm_adl_API.SetValue("cmi.completion_status", "incomplete");
}
}
function mm_adlOnunload()
{
if (mm_adl_API != null)
{
mm_adl_API.SetValue("cmi.completion_status", "incomplete");
mm_adl_API.Commit("");
}
}
GetAPI(window);
var nFindAPITries = 0;
var API = null;
var maxTries = 500;
function ScanForAPI(win)
{
while ((win.API_1484_11 == null) && (win.parent != null) && (win.parent != win))
{
nFindAPITries++;
if (nFindAPITries > maxTries)
{
return null;
}
win = win.parent;
}
return win.API_1484_11;
}
function GetAPI(win)
{
if ((win.parent != null) && (win.parent != win))
{
API = ScanForAPI(win.parent);
}
if ((API == null) && (win.opener != null))
{
API = ScanForAPI(win.opener);
}
}
5) SCORM: external file "SCOcomplete.js"
var nFindAPITries = 0;
var API = null;
var maxTries = 500;
function ScanForAPI(win)
{
while ((win.API_1484_11 == null) && (win.parent != null) && (win.parent != win))
{
nFindAPITries++;
if (nFindAPITries > maxTries)
{
return null;
}
win = win.parent;
}
return win.API_1484_11;
}
function GetAPI(win)
{
if ((win.parent != null) && (win.parent != win))
{
API = ScanForAPI(win.parent);
}
if ((API == null) && (win.opener != null))
{
API = ScanForAPI(win.opener);
}
}
function mm_adlOnload()
{
if (mm_adl_API != null)
{
mm_adl_API.SetValue("cmi.completion_status", "incomplete");
}
}
function mm_adlOnunload()
{
if (mm_adl_API != null)
{
mm_adl_API.SetValue("cmi.completion_status", "completed");
mm_adl_API.Commit("");
mm_adl_API.Terminate("");
}
}
GetAPI();
What am I doing wrong? If anybody at least has a working example of a similar SCORM 2004 project or can see what I might be doing wrong, it would be greatly appreciated.
Many, many thanks in advance!
You're calling Terminate() immediately after SetValue(). You must invoke Commit() after SetValue() to persist (save) the data in the database. Otherwise you're exiting the SCO without having saved anything.
Also, have you checked to ensure the value of scoPage[i] is accurate?
Building off your example couple others things.
I don't see a ("cmi.exit", "suspend") set. If you don't set that up right, the LMS will commonly re-launch a new attempt (clean).
Single Page SCOs vs Multi page SCOs typically contained within a IFRAME/Frameset or AJAX load setting 'cmi.location' may not result in the behavior your trying to achieve.
So if you have a lesson/unit/chapter (imsmanifest.xml) made up of individual pages as each page they view you'll want to auto-score them or base it on something they are interacting with.
cmi.location '2' (or whatever page your on) - only if your in a multipage SCO
cmi.success_status "passed" or "failed"
cmi.completion_status "completed" or "incomplete"
cmi.session_time - requires a ISO8601 duration
cmi.score.scaled 1 or 0 (min, max, raw if you want too)
cmi.exit ('normal' or 'suspend')
commit()
terminate()
cmi.total_time - managed by the LMS (they add last session time + current session time)
All depends on your single vs multi page. If single page you'll exit normal, no bookmark needed. The LMS will mark each item in the TOC completed/scored as you progress.
Good Luck

Insert a Link Using CSS

I'm hand-maintaining an HTML document, and I'm looking for a way to automatically insert a link around text in a table. Let me illustrate:
<table><tr><td class="case">123456</td></tr></table>
I would like to automatically make every text in a TD with class "case" a link to that case in our bug tracking system (which, incidentally, is FogBugz).
So I'd like that "123456" to be changed to a link of this form:
123456
Is that possible? I've played with the :before and :after pseudo-elements, but there doesn't seem to be a way to repeat the case number.
Not in a manner that will work across browsers. You could, however, do that with some relatively trivial Javascript..
function makeCasesClickable(){
var cells = document.getElementsByTagName('td')
for (var i = 0, cell; cell = cells[i]; i++){
if (cell.className != 'case') continue
var caseId = cell.innerHTML
cell.innerHTML = ''
var link = document.createElement('a')
link.href = 'http://bugs.example.com/fogbugz/default.php?' + caseId
link.appendChild(document.createTextNode(caseId))
cell.appendChild(link)
}
}
You can apply it with something like onload = makeCasesClickable, or simply include it right at the end of the page.
here is a jQuery solution specific to your HTML posted:
$('.case').each(function() {
var link = $(this).html();
$(this).contents().wrap('');
});
in essence, over each .case element, will grab the contents of the element, and throw them into a link wrapped around it.
Not possible with CSS, plus that's not what CSS is for any way. Client-side Javascript or Server-side (insert language of choice) is the way to go.
I don't think it's possible with CSS. CSS is only supposed to affect the looks and layout of your content.
This seems like a job for a PHP script (or some other language). You didn't give enough information for me to know the best way to do it, but maybe something like this:
function case_link($id) {
return '' . $id . '';
}
Then later in your document:
<table><tr><td class="case"><?php echo case_link('123456'); ?></td></tr></table>
And if you want an .html file, just run the script from the command line and redirect the output to an .html file.
You could have something like this (using Javascript). Inside <head>, have
<script type="text/javascript" language="javascript">
function getElementsByClass (className) {
var all = document.all ? document.all :
document.getElementsByTagName('*');
var elements = new Array();
for (var i = 0; i < all.length; i++)
if (all[i].className == className)
elements[elements.length] = all[i];
return elements;
}
function makeLinks(className, url) {
nodes = getElementsByClass(className);
for(var i = 0; i < nodes.length; i++) {
node = nodes[i];
text = node.innerHTML
node.innerHTML = '' + text + '';
}
}
</script>
And then at the end of <body>
<script type="text/javascript" language="javascript">
makeLinks("case", "http://bugs.example.com/fogbugz/default.php?");
</script>
I've tested it, and it works fine.
I know this is an old question, but I stumbled upon this post looking for a solution for creating hyperlinks using CSS and ended up making my own, could be of interest for someone stumbling across this question like I did:
Here's a php function called 'linker();'that enables a fake CSS attribute
connect: 'url.com';
for an #id defined item.
just let the php call this on every item of HTML you deem link worthy.
the inputs are the .css file as a string, using:
$style_cont = file_get_contents($style_path);
and the #id of the corresponding item. Heres the whole thing:
function linker($style_cont, $id_html){
if (strpos($style_cont,'connect:') !== false) {
$url;
$id_final;
$id_outer = '#'.$id_html;
$id_loc = strpos($style_cont,$id_outer);
$connect_loc = strpos($style_cont,'connect:', $id_loc);
$next_single_quote = stripos($style_cont,"'", $connect_loc);
$next_double_quote = stripos($style_cont,'"', $connect_loc);
if($connect_loc < $next_single_quote)
{
$link_start = $next_single_quote +1;
$last_single_quote = stripos($style_cont, "'", $link_start);
$link_end = $last_single_quote;
$link_size = $link_end - $link_start;
$url = substr($style_cont, $link_start, $link_size);
}
else
{
$link_start = $next_double_quote +1;
$last_double_quote = stripos($style_cont, '"', $link_start);
$link_end = $last_double_quote;
$link_size = $link_end - $link_start;
$url = substr($style_cont, $link_start, $link_size); //link!
}
$connect_loc_rev = (strlen($style_cont) - $connect_loc) * -1;
$id_start = strrpos($style_cont, '#', $connect_loc_rev);
$id_end = strpos($style_cont,'{', $id_start);
$id_size = $id_end - $id_start;
$id_raw = substr($style_cont, $id_start, $id_size);
$id_clean = rtrim($id_raw); //id!
if (strpos($url,'http://') !== false)
{
$url_clean = $url;
}
else
{
$url_clean = 'http://'.$url;
};
if($id_clean[0] == '#')
{
$id_final = $id_clean;
if($id_outer == $id_final)
{
echo '<a href="';
echo $url_clean;
echo '" target="_blank">';
};
};
};
};
this could probably be improved/shortened using commands like .wrap() or getelementbyID()
because it only generates the <a href='blah'> portion, but seeing as </a> disappears anyway without a opening clause it still works if you just add them everywhere :D