enable CSS and JavaScript from external URLs
authornetniV <netniv@hotmail.com>
Tue, 13 Nov 2018 10:45:20 +0000 (10:45 +0000)
committerDenis Ovsienko <denis@ovsienko.info>
Mon, 19 Nov 2018 11:19:31 +0000 (11:19 +0000)
ChangeLog
README.md
tests/PureFunctionTest.php
wwwroot/inc/init.php
wwwroot/inc/interface-8021q.php
wwwroot/inc/interface-config.php
wwwroot/inc/interface-lib.php
wwwroot/inc/interface.php
wwwroot/inc/popup.php
wwwroot/inc/slb2-interface.php
wwwroot/inc/upgrade.php

index ca05b1f..787704b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,5 @@
 0.21.2
+       update: enable CSS and JavaScript from external URLs (GH#231)
        update: 802.1Q: do permission check for changing native vlan while keeping the allowed vlans list unchanged
        update: 802.1Q: foreign VLANs (missing from the vlan domain list) are not propagated to uplinks
        update: ability to extend supported device breed list via plug-in
index b718eec..263e285 100644 (file)
--- a/README.md
+++ b/README.md
@@ -168,6 +168,39 @@ and initialize the application.
 This version drops support for the `$localreports` global variable, which is
 trivial to replace in a local plugin if necessary.
 
+There has been a separation of the `addJS` and `addCSS` functions to easily 
+identify the resource usage.  The original `addJS` and `addCSS` functions will 
+most likely to be removed in 0.22.0 as they are depreciated.
+
+- *`addJSText`/`addCSSText`*
+
+  These functions should be used to add inline JS/CSS 
+  not defined in a separate file.
+
+- *`addJSInternal`/`addCSSInternal`*
+
+  These functions should be used to add an internal reference to a JS/CSS file 
+  which is accessed using the `?module=chrome&uri=` for self hosted JS/CSS 
+  files.  This can be utilised by both the core and plugins.
+
+- *`addJSExternal`/`addCSSExternal`*
+
+  These functions should be used to add an external reference to a JS/CSS file 
+  which hosted on an external site or CDN. This can be utilised by both the core 
+  and plugins.
+
+Each of these functions expect the first parameter to be the data or URI, and 
+the second parameter to be an optional group.  By default, the group is set to 
+'default' and groups are sorted alphabetically.  It should be noted that when 
+the `addJSInternal` function is used, it will also add the jQuery and RackTables 
+common JavaScript functons.
+
+Due to this separation, you will no longer need to supply a TRUE or FALSE to 
+identify whether the parameter value is text or a URI.  If you rename an 
+existing `addJS`/`addCSS` function call, be sure to remove this parameter. 
+Failure to do so will mean you are effectively be saying that the group name is 
+'' (false) or '1' (true).
+
 ### Upgrading to 0.21.0
 
 From now on the minimum (oldest) release of PHP that can run RackTables is
@@ -355,3 +388,4 @@ besides 'yes' and 'no': 'none'. Use 'none' value if you are experiencing low
 performance on IP tree page. It will completely disable IP ranges scan for
 used/spare IPs and the speed of IP tree will increase radically. The price is
 you will not see the routers in IP tree at all.
+
index 1c51d22..e8eeefa 100644 (file)
@@ -503,6 +503,15 @@ class PureFunctionTest extends RTTestCase
                        array ('datetimeFormatHint', '%Y-%m-%d', 'YYYY-MM-DD'),
                        array ('datetimeFormatHint', '%d/%m/%y', 'DD/MM/YY'),
                        array ('datetimeFormatHint', '%d.%m.%Y', 'DD.MM.YYYY'),
+
+                       // validate various URI/URL combinations
+                       array ('isUri', 'https://www.test.com', FALSE),
+                       array ('isUri', '/js/table.js', TRUE),
+                       array ('isUri', '!#$%', FALSE),
+
+                       array ('isUrl', 'https://www.test.com', TRUE),
+                       array ('isUrl', '/js/table.js', FALSE),
+                       array ('isUrl', '!#$%', FALSE),
                );
        }
 
index e505a17..4780b8e 100644 (file)
@@ -109,12 +109,17 @@ $user_given_tags = array();
 // text that uses autotags generated by local plugins.
 $user_defined_atags = array();
 
+// Initial the HTML header arrays used by addJSxxx() and addCSSxxx() functions
+global $html_headers, $seen_headers;
+$html_headers = array();
+$seen_headers = array();
+
 // This also can be modified in local.php.
 $pageheaders = array
 (
        100 => "<link rel='ICON' type='image/x-icon' href='?module=chrome&uri=pix/favicon.ico' />",
 );
-addCSS ('css/pi.css');
+addCSSInternal ('css/pi.css');
 
 if (! isset ($script_mode) || $script_mode !== TRUE)
 {
@@ -167,4 +172,5 @@ $impl_tags = array();
 // Initial chain for the current target.
 $target_given_tags = array();
 
+// Now we've finished let plugins know
 callHook ('initFinished');
index 46f76f2..5c3ce32 100644 (file)
@@ -1180,7 +1180,7 @@ function renderObject8021QSyncPreview ($object, $vswitch, $plan, $C, $R, $maxdec
        switchportInfoJS ($vswitch['object_id']); // load JS code to make portnames interactive
        // Initialize one of the three popups: the data is ready.
        $port_config = addslashes (json_encode (formatPortConfigHints ($vswitch['object_id'], $R)));
-       addJS (<<<'END'
+       addJSText (<<<'END'
 $(document).ready(function(){
        var confData = $.parseJSON('$port_config');
        applyConfData(confData);
@@ -1222,7 +1222,7 @@ END
        echo '<tr valign=top><th>port</th><th width="40%">last&nbsp;saved&nbsp;version</th>';
        if ($maxdecisions)
        {
-               addJS ('js/racktables.js');
+               addJSInternal ('js/racktables.js');
                printOpFormIntro ('resolve8021QConflicts', array ('mutex_rev' => $vswitch['mutex_rev']));
                foreach (array ('left', 'asis', 'right') as $pos)
                        echo "<th class=tdcenter><input type=radio name=column_radio value=${pos} " .
@@ -1525,7 +1525,7 @@ function renderVSTRulesEditor ($vst_id)
                foreach (listCells ('vst') as $vst_id => $vst_info)
                        if ($vst_info['rulec'])
                                $source_options[$vst_id] = '(' . $vst_info['rulec'] . ') ' . $vst_info['description'];
-       addJS ('js/vst_editor.js');
+       addJSInternal ('js/vst_editor.js');
        echo '<center><h1>' . stringForLabel ($vst['description']) . '</h1></center>';
        if (count ($source_options))
        {
@@ -1552,7 +1552,7 @@ function renderVSTRulesEditor ($vst_id)
        $row_html .= '<td><input type=text name=wrt_vlans value="%s"></td>';
        $row_html .= '<td><input type=text name=description value="%s"></td>';
        $row_html .= '<td><a href="#" class="vst-add-rule">' . getImageHREF ('add', 'Duplicate rule') . '</a></td>';
-       addJS ("var new_vst_row = '" . addslashes (sprintf ($row_html, '', '', getSelect ($port_role_options, array ('name' => 'port_role'), 'anymode'), '', '')) . "';", TRUE);
+       addJSText ("var new_vst_row = '" . addslashes (sprintf ($row_html, '', '', getSelect ($port_role_options, array ('name' => 'port_role'), 'anymode'), '', '')) . "';", TRUE);
        startSession();
        foreach (array_fetch ($_SESSION, 'vst_edited', $vst['rules']) as $item)
                printf ('<tr>' . $row_html . '</tr>', $item['rule_no'], htmlspecialchars ($item['port_pcre'], ENT_QUOTES),  getSelect ($port_role_options, array ('name' => 'port_role'), $item['port_role']), $item['wrt_vlans'], $item['description']);
index 1a9a98f..8ac530a 100644 (file)
@@ -96,10 +96,10 @@ function renderUserProperties ($user_id)
 function renderRackCodeViewer ()
 {
        echo '<table width="100%" border=0>';
-       addJS ('js/codemirror/codemirror.js');
-       addJS ('js/codemirror/rackcode.js');
-       addCSS ('css/codemirror/codemirror.css');
-       addCSS ('css/codemirror/rackcode.css');
+       addJSInternal ('js/codemirror/codemirror.js');
+       addJSInternal ('js/codemirror/rackcode.js');
+       addCSSInternal ('css/codemirror/codemirror.css');
+       addCSSInternal ('css/codemirror/rackcode.css');
        if (! array_key_exists ('line', $_REQUEST))
                $scrollcode = '';
        else
@@ -110,7 +110,7 @@ function renderRackCodeViewer ()
                        "rackCodeMirror.scrollIntoView ({line: ${lineno}, ch: 0}, 50);\n";
        }
        // Heredoc, not nowdoc!
-       addJS (<<<"ENDJAVASCRIPT"
+       addJSText (<<<"ENDJAVASCRIPT"
 $(document).ready(function() {
        var rackCodeMirror = CodeMirror.fromTextArea(document.getElementById("RCTA"),{
                mode:'rackcode',
@@ -128,11 +128,11 @@ ENDJAVASCRIPT
 
 function renderRackCodeEditor ()
 {
-       addJS ('js/codemirror/codemirror.js');
-       addJS ('js/codemirror/rackcode.js');
-       addCSS ('css/codemirror/codemirror.css');
-       addCSS ('css/codemirror/rackcode.css');
-       addJS (<<<'ENDJAVASCRIPT'
+       addJSInternal ('js/codemirror/codemirror.js');
+       addJSInternal ('js/codemirror/rackcode.js');
+       addCSSInternal ('css/codemirror/codemirror.css');
+       addCSSInternal ('css/codemirror/rackcode.css');
+       addJSText (<<<'ENDJAVASCRIPT'
 function verify()
 {
        $.ajax({
@@ -959,7 +959,7 @@ function renderTagRowForEditor ($taginfo, $parent_name = NULL, $level = 0)
 
 function addParentNodeOptionsJS ($prefix, $nodetype)
 {
-       addJS
+       addJSText
        (
 // Heredoc, not nowdoc!
 <<<"END"
index eede563..6406032 100644 (file)
@@ -403,8 +403,8 @@ function getOptionTree ($tree_name, $tree_options, $tree_config = array())
                'empty_value' => '',
                'indexed' => TRUE,
        );
-       addJS ('js/jquery.optionTree.js');
-       addJS ("
+       addJSInternal ('js/jquery.optionTree.js');
+       addJSText ("
 $(function() {
        var option_tree = " . json_encode ($tree_options) . ";
        var options = " . json_encode ($tree_config + $default_config) . ";
@@ -497,47 +497,123 @@ function transformRequestData()
                $_SERVER['REMOTE_USER'] = escapeString ($_SERVER['REMOTE_USER']);
 }
 
-// JS scripts should be included through this function.
-// They automatically appear in the <head> of your page.
-// $data is a JS filename, or JS code w/o tags around, if $inline = TRUE
-// Scripts are included in the order of adding within the same group, and groups are sorted alphabetically.
+// Return whether value passed is likely to be a Uri
+function isUri ($uri)
+{
+       return preg_match ('~^[\w\-\._\/ ]+$~', $uri);
+}
+
+// Return whether value passed is likely to be a Url
+function isUrl ($url)
+{
+       return preg_match ('~^[\w]+:\/\/[\w \-\.\_\/]+$~', $url);
+}
+
+// JS scripts should be included through the addJS* functions. They will automatically appear in the <head> of your page.
+// the addJS function has been replaced by addJSInternal, addJSExternal and addJSText() functions.  This function will be
+// removed in 2.22.0
 function addJS ($data, $inline = FALSE, $group = 'default')
 {
-       static $javascript = array();
-       static $seen_data = array();
+       if ($inline)
+               addJSText ($data, $group);
+       else if (isURL ($data))
+               addJSExternal ($data, $group);
+       else
+               addJSInternal ($data, $group);
+}
+
+// addJSExternal links to external scripts via URL and must be prefixed with
+// either http:// or https://
+function addJSExternal ($url, $group = 'default')
+{
+       global $html_headers, $seen_headers;
 
-       if (! isset ($data))
+       if (! isUrl ($url))
+               throw new InvalidArgException ('url', $url, 'Value passed is not a URL');
+
+       $url = "<script type='text/javascript' src='${url}'></script>\n";
+       if (!isset ($seen_headers[$url]))
        {
-               ksort ($javascript);
-               return $javascript;
+               $html_headers[$group][] = $url;
+               $seen_headers[$url] = 1;
        }
+}
+
+// addJSInternal adds links that go through the Chrome module of index.php
+function addJSInternal ($uri, $group = 'default')
+{
+       global $html_headers, $seen_headers;
+
        // Add jquery.js and racktables.js the first time a Javascript file is added.
-       if (! count ($javascript))
+       if (! array_key_exists ('a_core', $html_headers))
+       {
+               $html_headers['a_core'] = array();
+
+               addJSInternal('js/jquery-1.4.4.min.js', 'a_core');
+               addJSInternal('js/racktables.js',       'a_core');
+       }
+
+       if (! isUri ($uri))
+               throw new InvalidArgException ('uri', $uri, 'Value passed is not a valid Uri');
+
+       $uri = "<script type='text/javascript' src='?module=chrome&uri=${uri}'></script>\n";
+       if (! isset ($seen_headers[$uri]))
+       {
+               $html_headers[$group][] = $uri;
+               $seen_headers[$uri] = 1;
+       }
+}
+
+// This function adds script blocks that automatically appear in the <head> of your page.
+// Scripts are included in the order of adding within the same group, and groups are sorted alphabetically.
+function addJSText ($text, $group = 'default')
+{
+       global $html_headers, $seen_headers;
+
+       if (isUrl ($text))
+               throw new InvalidArgException ('text', $text, 'Value passed is most likely a Url and should use addJSExternal');
+
+       if (isUri ($text))
+               throw new InvalidArgException ('text', $text, 'Value passed is most likely a Uri and should use addJSInternal');
+
+       $text = '<script type="text/javascript">' . "\n" . trim ($text, "\r\n") . "\n</script>\n";
+       if (! isset ($seen_headers[$text]))
        {
-               $javascript = array
-               (
-                       'a_core' => array
-                       (
-                               array('type' => 'file', 'script' => 'js/jquery-1.4.4.min.js'),
-                               array('type' => 'file', 'script' => 'js/racktables.js'),
-                       ),
-               );
-
-               // initialize core js filelist
-               foreach ($javascript as $group_name => $group_array)
-                       foreach ($group_array as $item)
-                               if ($item['type'] == 'file')
-                                       $seen_data[$item['script']] = 1;
+               $html_headers[$group][] = $text;
+               $seen_headers[$text] = 1;
        }
+}
+
+// CSS styles should be included through this function.
+// They automatically appear in the <head> of your page.
+// $data is a CSS filename, or CSS code w/o tags around, if $inline = TRUE
+// Styles are included in the order of adding.
+function addCSS ($data, $inline = FALSE, $group = 'default')
+{
+       if ($inline)
+               addCSSText ($data, $group);
+       else if (isURL ($data))
+               addCSSExternal ($data, $group);
+       else
+               addCSSInternal ($data, $group);
+}
+
+// CSS styles should be included through this function.
+// They automatically appear in the <head> of your page.
+// $data is a CSS filename, or CSS code w/o tags around, if $inline = TRUE
+// Styles are included in the order of adding.
+function addCSSExternal ($url, $group = 'default')
+{
+       global $html_headers, $seen_headers;
+
+       if (! isUrl ($url))
+               throw new InvalidArgException ('url', $url, 'Value passed is not a valid Url');
 
-       if (! isset ($seen_data[$data]))
+       $url = "<link rel=stylesheet type='text/css' href='$url' />\n";
+       if (! isset ($seen_headers[$url]))
        {
-               $javascript[$group][] = array
-               (
-                       'type' => $inline ? 'inline' : 'file',
-                       'script' => $data,
-               );
-               $seen_data[$data] = 1;
+               $html_headers[$group][] = $url;
+               $seen_headers[$url] = 1;
        }
 }
 
@@ -545,21 +621,40 @@ function addJS ($data, $inline = FALSE, $group = 'default')
 // They automatically appear in the <head> of your page.
 // $data is a CSS filename, or CSS code w/o tags around, if $inline = TRUE
 // Styles are included in the order of adding.
-function addCSS ($data, $inline = FALSE)
+function addCSSInternal ($uri, $group = 'default')
 {
-       static $styles = array();
-       static $seen_data = array();
+       global $html_headers, $seen_headers;
 
-       if (! isset ($data))
-               return $styles;
-       if (! isset ($seen_data[$data]))
+       if (! isUri ($uri))
+               throw new InvalidArgException ('uri', $uri, 'Value passed is not a valid Uri');
+
+       $uri = "<link rel=stylesheet type='text/css' href='?module=chrome&uri=$uri' />\n";
+       if (! isset ($seen_headers[$uri]))
        {
-               $styles[] = array
-               (
-                       'type' => $inline ? 'inline' : 'file',
-                       'style' => $data,
-               );
-               $seen_data[$data] = 1;
+               $html_headers[$group][] = $uri;
+               $seen_headers[$uri] = 1;
+       }
+}
+
+// CSS styles should be included through this function.
+// They automatically appear in the <head> of your page.
+// $data is a CSS filename, or CSS code w/o tags around, if $inline = TRUE
+// Styles are included in the order of adding.
+function addCSSText ($text, $group = 'default')
+{
+       global $html_headers, $seen_headers;
+
+       if (isUrl ($text))
+               throw new InvalidArgException ('text', $text, 'Value passed is most likely a Url and should use addCSSExternal');
+
+       if (isUri ($text))
+               throw new InvalidArgException ('text', $text, 'Value passed is most likely a Uri and should use addCSSInternal');
+
+       $text = '<style type="text/css">' . "\n" . trim ($text, "\r\n") . "\n</style>\n";
+       if (! isset ($seen_headers[$text]))
+       {
+               $html_headers[$group][] = $text;
+               $seen_headers[$text] = 1;
        }
 }
 
@@ -630,7 +725,7 @@ function getRenderedIPv4NetCapacity ($range)
        {
                // fast mode
                $class .= ' pending';
-               addJS ('js/net-usage.js');
+               addJSInternal ('js/net-usage.js');
 
                $free_text = '';
                if (isset ($range['kidc']) && $range['kidc'] > 0)
@@ -661,7 +756,7 @@ function getRenderedIPv6NetCapacity ($range)
        {
                $used = NULL;
                $class .= ' pending';
-               addJS ('js/net-usage.js');
+               addJSInternal ('js/net-usage.js');
        }
 
        static $prefixes = array
@@ -709,22 +804,15 @@ function printPageHeaders ()
        foreach ($pageheaders as $s)
                echo $s . "\n";
        // add tabindex to all input forms
-       addJS ('js/tabindex_auto.js', FALSE);
-
-       // add CSS styles
-       foreach (addCSS (NULL) as $item)
-               if ($item['type'] == 'inline')
-                       echo '<style type="text/css">' . "\n" . trim ($item['style'], "\r\n") . "\n</style>\n";
-               elseif ($item['type'] == 'file')
-                       echo "<link rel=stylesheet type='text/css' href='?module=chrome&uri=${item['style']}' />\n";
-
-       // add JS scripts
-       foreach (addJS (NULL) as $group_name => $js_list)
-               foreach ($js_list as $item)
-                       if ($item['type'] == 'inline')
-                               echo '<script type="text/javascript">' . "\n" . trim ($item['script'], "\r\n") . "\n</script>\n";
-                       elseif ($item['type'] == 'file')
-                               echo "<script type='text/javascript' src='?module=chrome&uri=${item['script']}'></script>\n";
+       addJSInternal ('js/tabindex_auto.js');
+
+       // add JS/CSS headers
+       global $html_headers;
+       ksort($html_headers);
+
+       foreach ($html_headers as $group_name => $list)
+               foreach ($list as $index => $item)
+                       echo "<!-- $group_name:$index -->\n" . $item;
 }
 
 function cmpTags ($a, $b)
@@ -928,7 +1016,7 @@ function getOpLink ($params, $title,  $img_name = '', $comment = '', $class = ''
                        $ret .= ' ';
        }
        if (FALSE !== strpos ($class, 'need-confirmation'))
-               addJS ('js/racktables.js');
+               addJSInternal ('js/racktables.js');
        $ret .= $title . '</a>';
        return $ret;
 }
@@ -999,9 +1087,9 @@ function getRenderedNetVLAN ($cell)
 
 function includeJQueryUI ($do_css = TRUE)
 {
-       addJS ('js/jquery-ui-1.8.21.min.js');
+       addJSInternal ('js/jquery-ui-1.8.21.min.js');
        if ($do_css)
-               addCSS ('css/jquery-ui-1.8.22.redmond.css');
+               addCSSInternal ('css/jquery-ui-1.8.22.redmond.css');
 }
 
 function getRenderedIPPortPair ($ip, $port = NULL)
@@ -1160,9 +1248,9 @@ function enableTagsPicker ()
        global $taglist;
        static $taglist_inserted;
        includeJQueryUI ();
-       addCSS ('css/tagit.css');
-       addJS ('js/tag-it.js');
-       addJS ('js/tag-it-local.js');
+       addCSSInternal ('css/tagit.css');
+       addJSInternal ('js/tag-it.js');
+       addJSInternal ('js/tag-it-local.js');
        if (! $taglist_inserted)
        {
                $taglist_filtered = array();
@@ -1172,7 +1260,7 @@ function enableTagsPicker ()
                        if ($taginfo['color'] != NULL)
                                $taglist_filtered[$key]['tagclass'] = getTagClass ($taginfo);
                }
-               addJS ('var taglist = ' . json_encode ($taglist_filtered) . ';', TRUE);
+               addJSText ('var taglist = ' . json_encode ($taglist_filtered) . ';');
                $taglist_inserted = TRUE;
        }
 }
@@ -1242,7 +1330,7 @@ function getCachedCSSClassForStyle ($class, $style)
        $cachedclass = array_search ($style, $cache);
        if ($cachedclass !== FALSE)
                return " $cachedclass";
-       addCSS (".{$class} {{$style}}", TRUE);
+       addCSSText (".{$class} {{$style}}");
        $cache[$class] = $style;
        return " $class";
 }
index f7a8e20..e9c461d 100644 (file)
@@ -363,7 +363,7 @@ function expand(id) {
        }
 }
 END
-       ,TRUE);
+       );
        startPortlet ('Location filter');
        echo <<<'END'
 <table border=0 align=center cellspacing=0 class="tagtree" id="locationFilter">
@@ -596,7 +596,7 @@ function renderRackspaceLocationEditor ()
        });
 JSTXT;
 
-       addJS($js, TRUE );
+       addJS($js);
        function printNewItemTR ()
        {
                printOpFormIntro ('addLocation');
@@ -1066,7 +1066,7 @@ function renderRackSortForm ($row_id)
                }
        );
 JSTXT;
-       addJS ($js, TRUE);
+       addJSText ($js);
 
        startPortlet ('Racks');
        echo "<table border=0 cellspacing=0 cellpadding=5 align=center class=widetable>\n";
@@ -1321,7 +1321,7 @@ function renderGridForm ($rack_id, $filter, $header, $submit, $state1, $state2)
        $is_ro = !rackModificationPermitted ($rackData, 'updateRack');
        startPortlet ($header);
        includeJQueryUI (FALSE);
-       addJS ('js/racktables.js');
+       addJSInternal ('js/racktables.js');
        $table_id = 'selectableRack';
        addBulkSelectorJS ($table_id);
        echo "<center>\n";
@@ -1510,7 +1510,7 @@ function renderObject ($object_id)
                foreach ($info['ports'] as $port)
                        callHook ('renderObjectPortRow', $port, ($hl_port_id == $port['id']));
                if (permitted (NULL, 'ports', 'set_reserve_comment'))
-                       addJS ('js/inplace-edit.js');
+                       addJSInternal ('js/inplace-edit.js');
                echo "</table><br>";
                finishPortlet();
        }
@@ -1831,7 +1831,7 @@ function renderIPForObject ($object_id)
                includeJQueryUI (TRUE);
 
                // Heredoc, not nowdoc!
-               addJS (<<<"JSEND"
+               addJSText (<<<"JSEND"
                        $(document).ready( function() {
                                $('[name="bond_name"]').autocomplete({
                                        source: "?module=ajax&ac=autocomplete&realm=bond_name&object_id=$object_id",
@@ -1847,7 +1847,7 @@ function renderIPForObject ($object_id)
                                });
                        });
 JSEND
-               , TRUE);
+               );
                printOpFormIntro ('add');
                echo "<tr><td>"; // left btn
                printImageHREF ('add', 'allocate', TRUE);
@@ -2146,7 +2146,7 @@ function renderPortsInfo($object_id)
 function addBulkSelectorJS ($element_id)
 {
        // Heredoc, not nowdoc!
-       addJS (<<<"ENDOFJAVASCRIPT"
+       addJSText (<<<"ENDOFJAVASCRIPT"
 $(function () {
     $("#{$element_id} tbody").selectable({
         filter: 'td.atom',
@@ -2159,7 +2159,7 @@ $(function () {
     });
 });
 ENDOFJAVASCRIPT
-, TRUE);
+       );
 }
 
 // An object can be mounted onto free atoms only, that is, if any record for an atom
@@ -2260,7 +2260,7 @@ function renderRackSpaceForObject ($object_id)
        echo "<td class=pcright rowspan=2 height='1%'>";
        startPortlet ('Working copy');
        includeJQueryUI (false);
-       addJS ('js/racktables.js');
+       addJSInternal ('js/racktables.js');
        echo '<table border=0 cellspacing=10 align=center><tr>';
        foreach ($workingRacksData as $rack_id => $rackData)
        {
@@ -2725,16 +2725,16 @@ function renderIPNewNetForm ()
        }
 
        // IP prefix validator
-       addJS ('js/live_validation.js');
+       addJSInternal ('js/live_validation.js');
        $regexp = addslashes ($regexp);
        // Heredoc, not nowdoc!
-       addJS (<<<"END"
+       addJSText (<<<"END"
 $(document).ready(function () {
        $('form#add input[name="range"]').attr('match', '$regexp');
        Validate.init();
 });
 END
-       , TRUE);
+       );
 
        startPortlet ('Add new');
        printOpFormIntro ('add');
@@ -3091,7 +3091,7 @@ function renderIPv4NetworkAddresses ($range)
        }
        // end of iteration
        if (permitted (NULL, NULL, 'set_reserve_comment'))
-               addJS ('js/inplace-edit.js');
+               addJSInternal ('js/inplace-edit.js');
 
        echo "</table>";
        if ($rendered_pager != '')
@@ -3227,7 +3227,7 @@ function renderIPv6NetworkAddresses ($netinfo)
        }
        echo "</table>";
        if (permitted (NULL, NULL, 'set_reserve_comment'))
-               addJS ('js/inplace-edit.js');
+               addJSInternal ('js/inplace-edit.js');
 }
 
 function renderIPNetworkProperties ($id)
@@ -3408,7 +3408,7 @@ function renderIPAddressAllocations ($ip_bin)
 
                includeJQueryUI (TRUE);
 
-               addJS (<<<'JSEND'
+               addJSText (<<<'JSEND'
                        $(document).ready( function() {
                                $('[name="bond_name"]').autocomplete({
                                        //minLength: 3,
@@ -3430,7 +3430,7 @@ function renderIPAddressAllocations ($ip_bin)
                                });
                        });
 JSEND
-               , TRUE);
+               );
                printOpFormIntro ('add');
                echo "<tr id='aid-new'><td>";
                printImageHREF ('add', 'allocate', TRUE);
@@ -3960,7 +3960,7 @@ function renderAtomGrid ($data, $is_ro = FALSE)
        markAllSpans ($data);
        $rack_id = $data['id'];
        $reverse = considerConfiguredConstraint ($data, 'REVERSED_RACKS_LISTSRC');
-       addJS ('js/racktables.js');
+       addJSInternal ('js/racktables.js');
        for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
        {
                $unit_label = inverseRackUnit ($data['height'], $unit_no, $reverse);
@@ -4380,7 +4380,7 @@ function renderLivePTR ($id)
        if ($can_import && $box_counter > 1)
        {
                echo '<tr><td colspan=3 align=center><input type=submit value="Import selected records"></td><td>';
-               addJS ('js/racktables.js');
+               addJSInternal ('js/racktables.js');
                echo --$box_counter ? "<a href='javascript:;' onclick=\"toggleColumnOfAtoms(1, 1, ${box_counter})\">(toggle selection)</a>" : '&nbsp;';
                echo '</td></tr>';
        }
@@ -4533,8 +4533,8 @@ function renderEntityTags ($entity_id)
                                $js_code .= "\n\t${tag['id']} : 1";
                        }
                        $js_code .= "\n});\n$(document).ready(tag_cb.compactTreeMode);";
-                       addJS ('js/tag-cb.js');
-                       addJS ($js_code, TRUE);
+                       addJSInternal ('js/tag-cb.js');
+                       addJSText ($js_code);
                }
        }
 
@@ -4549,8 +4549,8 @@ function renderEntityTags ($entity_id)
 // This one is going to replace the tag filter.
 function renderCellFilterPortlet ($preselect, $realm, $cell_list = array(), $bypass_params = array())
 {
-       addJS ('js/tag-cb.js');
-       addJS ('tag_cb.enableNegation()', TRUE);
+       addJSInternal ('js/tag-cb.js');
+       addJSText ('tag_cb.enableNegation()');
 
        global $pageno, $tabno, $taglist;
        $filterc =
@@ -4607,7 +4607,7 @@ function renderCellFilterPortlet ($preselect, $realm, $cell_list = array(), $byp
                }
 
                if (getConfigVar('SHRINK_TAG_TREE_ON_CLICK') == 'yes')
-                       addJS ('tag_cb.enableSubmitOnClick()', TRUE);
+                       addJSText ('tag_cb.enableSubmitOnClick()');
        }
        // predicates block
        if (getConfigVar ('FILTER_SUGGEST_PREDICATES') == 'yes' || count ($preselect['pnamelist']))
@@ -4682,7 +4682,7 @@ function renderCellFilterPortlet ($preselect, $realm, $cell_list = array(), $byp
                        echo " <a href=\"#\" onclick=\"textifyCellFilter(this, '$text'); return false\">";
                        printImageHREF ('COPY', 'Make text expression from current filter');
                        echo '</a>';
-                       addJS (<<<'END'
+                       addJSText (<<<'END'
 function textifyCellFilter(target, text)
 {
        var portlet = $(target).closest ('.portlet');
@@ -4691,7 +4691,6 @@ function textifyCellFilter(target, text)
        portlet.find ('input[type="radio"][value="and"]').attr('checked','true');
 }
 END
-                               , TRUE
                        );
                }
                echo '</td><td class=tdright>';
@@ -5911,7 +5910,7 @@ function renderDiscoveredNeighbors ($object_id)
        }
        echo '</table></form>';
 
-       addJS (<<<'END'
+       addJSText (<<<'END'
 $(document).ready(function () {
        $('#cb-toggle').click(function (event) {
                var list = $('.cb-makelink');
@@ -5922,7 +5921,6 @@ $(document).ready(function () {
        }).triggerHandler('click');
 });
 END
-               , TRUE
        );
 }
 
@@ -6074,14 +6072,14 @@ function formatAttributeValue ($record, $objtype_id)
 function addAutoScrollScript ($anchor_name)
 {
        // Heredoc, not nowdoc!
-       addJS (<<<"END"
+       addJSText (<<<"END"
 $(document).ready(function() {
        var anchor = document.getElementsByName('$anchor_name')[0];
        if (anchor)
                anchor.scrollIntoView(false);
 });
 END
-       , TRUE);
+       );
 }
 
 //
@@ -6293,11 +6291,11 @@ function switchportInfoJS($object_id)
                )
                        $allowed_ops[] = $prefix;
 
-       addJS ('js/jquery.thumbhover.js');
-       addCSS ('css/jquery.contextmenu.css');
-       addJS ('js/jquery.contextmenu.js');
-       addJS ("enabled_elements = " . json_encode ($allowed_ops), TRUE);
-       addJS ('js/portinfo.js');
+       addJSInternal ('js/jquery.thumbhover.js');
+       addCSSInternal ('css/jquery.contextmenu.css');
+       addJSInternal ('js/jquery.contextmenu.js');
+       addJSText ("enabled_elements = " . json_encode ($allowed_ops));
+       addJSInternal ('js/portinfo.js');
 }
 
 function renderIPAddressLog ($ip_bin)
index c7f5f92..d51eb29 100644 (file)
@@ -264,31 +264,31 @@ function handlePopupPortLink()
                                        showError ('failed to consume a patch cable');
                        }
                }
-               showOneLiner 
+               showOneLiner
                (
-                       8, 
+                       8,
                        array
                        (
                                formatPortLink ($port_info['object_id'], NULL, $port_info['id'], $port_info['name']),
                                formatPort ($remote_port_info),
                        )
                );
-               addJS (<<<'END'
+               addJSText (<<<'END'
 window.opener.location.reload(true);
 window.close();
 END
-               , TRUE);
+               );
                backupLogMessages();
        }
        else
        {
                // JS code to display port compatibility hint
                // Heredoc, not nowdoc!
-               addJS (<<<"END"
+               addJSText (<<<"END"
 POIFC = {};
 $js_table
 $(document).ready(function () {
-       $('select.porttype').change(onPortTypeChange);  
+       $('select.porttype').change(onPortTypeChange);
        onPortTypeChange();
 });
 function onPortTypeChange() {
@@ -305,8 +305,8 @@ function onPortTypeChange() {
        }
 }
 END
-               , TRUE);
-               addCSS (<<<'END'
+               );
+               addCSSText (<<<'END'
 .compat-hint {
        display: none;
        font-size: 125%;
@@ -318,7 +318,7 @@ END
        color: #804040;
 }
 END
-               , TRUE);
+               );
                // render port type editor form
                echo '<form method=GET>';
                echo '<input type=hidden name="module" value="popup">';
@@ -423,7 +423,7 @@ function renderPopupPortSelector()
        echo '</tr></table>';
        finishPortlet();
 
-       addJS (<<<'JSEND'
+       addJSText (<<<'JSEND'
                $(document).ready( function() {
                        $("#filter-obj").autocomplete({
                                source: "?module=ajax&ac=autocomplete&realm=object",
@@ -463,7 +463,7 @@ function renderPopupPortSelector()
                        });
                });
 JSEND
-       , TRUE);
+       );
 
        // display results
        startPortlet ('Compatible spare ports');
index 4412e70..e123cb2 100644 (file)
@@ -157,8 +157,8 @@ function renderEditVS ($vs_id)
        echo '</th></tr>';
        echo '</table></form>';
 
-       addJS ('js/jquery.thumbhover.js');
-       addJS ('js/slb_editor.js');
+       addJSInternal ('js/jquery.thumbhover.js');
+       addJSInternal ('js/slb_editor.js');
 
        // second form - ports and IPs settings
        echo '<p>'; // vertical indentation
@@ -326,8 +326,8 @@ function renderSLBTriplets2 ($cell, $editable = FALSE, $hl_ip = NULL)
                echo "</tr>";
        }
 
-       addJS ('js/slb_editor.js');
-       addJS ('js/jquery.thumbhover.js');
+       addJSInternal ('js/slb_editor.js');
+       addJSInternal ('js/jquery.thumbhover.js');
 
        $class = 'slb-checks';
        if ($editable)
@@ -584,15 +584,15 @@ function getPopupSLBConfig ($row)
        static $js_added = FALSE;
        if (! $js_added)
        {
-               addJS ('js/jquery.thumbhover.js');
-               addJS (<<<'END'
+               addJSInternal ('js/jquery.thumbhover.js');
+               addJSText (<<<'END'
 $(document).ready (function () {
        $('.slbconf-btn').each (function () {
                $(this).thumbPopup($(this).siblings('.slbconf.popup-box'), { showFreezeHint: false });
        });
 });
 END
-               , TRUE);
+               );
        }
        return $ret;
 }
index 23b6110..29be362 100644 (file)
@@ -178,6 +178,14 @@ ENDOFTEXT
 
 This version drops support for the $localreports global variable, which is
 trivial to replace in a local plugin if necessary.
+
+The "addJS()" function is now depreciated in favour of "addJSText()", "addJSInternal()",
+and "addJSExternal()" functions.  The "addJS()" function will likely be removed in 0.22.0
+
+The "addCSS()" function is now depreciated in favour of "addCSSText()", "addCSSInternal()",
+and "addCSSExternal()" functions.  The "addCSS()" function will likely be removed in 0.22.0
+
+For more information on the "addJS()" and "addCSS()" changes see the README.md
 ENDOFTEXT
 ,
 );