From 4d14a81936bc26fa09c4908362707201841036d1 Mon Sep 17 00:00:00 2001 From: Chris Gross <gross.364@osu.edu> Date: Mon, 12 Sep 2016 16:03:44 -0400 Subject: [PATCH] weekly build --- profiles/wcm_base/CHANGELOG.txt | 7 + .../modules/contrib/diff/CHANGELOG.txt | 166 ++ .../modules/contrib/diff/DiffEngine.php | 1349 +++++++++++++++++ .../wcm_base/modules/contrib/diff/LICENSE.txt | 339 +++++ .../modules/contrib/diff/css/diff.boxes.css | 124 ++ .../modules/contrib/diff/css/diff.default.css | 86 ++ .../modules/contrib/diff/diff.admin.inc | 158 ++ .../modules/contrib/diff/diff.api.php | 181 +++ .../wcm_base/modules/contrib/diff/diff.css | 86 ++ .../modules/contrib/diff/diff.diff.inc | 384 +++++ .../wcm_base/modules/contrib/diff/diff.info | 12 + .../modules/contrib/diff/diff.install | 124 ++ .../wcm_base/modules/contrib/diff/diff.module | 623 ++++++++ .../modules/contrib/diff/diff.pages.inc | 632 ++++++++ .../modules/contrib/diff/diff.theme.inc | 149 ++ .../modules/contrib/diff/diff.tokens.inc | 63 + .../modules/contrib/diff/includes/file.inc | 111 ++ .../modules/contrib/diff/includes/image.inc | 112 ++ .../modules/contrib/diff/includes/list.inc | 71 + .../modules/contrib/diff/includes/node.inc | 107 ++ .../modules/contrib/diff/includes/number.inc | 17 + .../contrib/diff/includes/taxonomy.inc | 107 ++ .../modules/contrib/diff/includes/text.inc | 113 ++ .../wcm_base/modules/contrib/diff/js/diff.js | 58 + .../wcm_base/modules/contrib/diff/readme.txt | 136 ++ .../draggableviews/draggableviews.info | 6 +- .../draggableviews/draggableviews.module | 17 + .../draggableviews_book.info | 6 +- .../draggableviews_test.info | 6 +- .../ocio_wysiwyg.features.wysiwyg.inc | 11 +- .../custom/ocio_wysiwyg/ocio_wysiwyg.module | 9 +- .../custom/ocio_wysiwyg/plugins/icon-tabs.png | Bin 344 -> 0 bytes .../ocio_wysiwyg/plugins/menuMods/plugin.js | 18 + .../ocio_wysiwyg/plugins/tabs/plugin.js | 1 + .../wcm_panels_settings.module | 13 + .../wcm_workbench/wcm_workbench.features.inc | 9 + .../custom/wcm_workbench/wcm_workbench.info | 8 + .../custom/wcm_workbench/wcm_workbench.make | 3 + .../custom/wcm_workbench/wcm_workbench.module | 36 + .../wcm_workbench/wcm_workbench.strongarm.inc | 49 + .../ocio-default/ocio-default.layout.css | 25 - .../ocio-default.layout.no-query.css | 25 - .../css/ocio-omega-base.no-query.css | 75 +- .../css/ocio-omega-base.styles.css | 75 +- .../ocio_omega_base/sass/base/_forms.scss | 38 - .../sass/components/_webform.scss | 72 +- 46 files changed, 5631 insertions(+), 186 deletions(-) create mode 100644 profiles/wcm_base/modules/contrib/diff/CHANGELOG.txt create mode 100644 profiles/wcm_base/modules/contrib/diff/DiffEngine.php create mode 100644 profiles/wcm_base/modules/contrib/diff/LICENSE.txt create mode 100644 profiles/wcm_base/modules/contrib/diff/css/diff.boxes.css create mode 100644 profiles/wcm_base/modules/contrib/diff/css/diff.default.css create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.admin.inc create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.api.php create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.css create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.diff.inc create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.info create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.install create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.module create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.pages.inc create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.theme.inc create mode 100644 profiles/wcm_base/modules/contrib/diff/diff.tokens.inc create mode 100644 profiles/wcm_base/modules/contrib/diff/includes/file.inc create mode 100644 profiles/wcm_base/modules/contrib/diff/includes/image.inc create mode 100644 profiles/wcm_base/modules/contrib/diff/includes/list.inc create mode 100644 profiles/wcm_base/modules/contrib/diff/includes/node.inc create mode 100644 profiles/wcm_base/modules/contrib/diff/includes/number.inc create mode 100644 profiles/wcm_base/modules/contrib/diff/includes/taxonomy.inc create mode 100644 profiles/wcm_base/modules/contrib/diff/includes/text.inc create mode 100644 profiles/wcm_base/modules/contrib/diff/js/diff.js create mode 100644 profiles/wcm_base/modules/contrib/diff/readme.txt delete mode 100644 profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/icon-tabs.png create mode 100644 profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/menuMods/plugin.js create mode 100644 profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.strongarm.inc diff --git a/profiles/wcm_base/CHANGELOG.txt b/profiles/wcm_base/CHANGELOG.txt index 621b9ada..3594ca60 100644 --- a/profiles/wcm_base/CHANGELOG.txt +++ b/profiles/wcm_base/CHANGELOG.txt @@ -1,3 +1,10 @@ +WCM Base 7.x-1.x, 2016-09-12 +---------------------------- +- WCM Workbench: Added diff module, including custom links in Workbench Block. +- WCM Panels Settings: Clear page cache when saving panelized nodes in panels IPE. +- OCIO WYSIWYG: Added custom plugin menuMod (removes fields in table cell dialog). +- OCIO Omega Base: Improved webform styles. + WCM Base 7.x-1.x, 2016-08-29 ---------------------------- - WCM Search: diff --git a/profiles/wcm_base/modules/contrib/diff/CHANGELOG.txt b/profiles/wcm_base/modules/contrib/diff/CHANGELOG.txt new file mode 100644 index 00000000..38696432 --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/CHANGELOG.txt @@ -0,0 +1,166 @@ + +CHANGELOG for Diff 7.x-2.0+13-dev to 7.x-3.x +============================================ + +1) System variable names have been changed +------------------------------------------ + +Considerable changes have occurred. + +2) hook_diff() was removed +-------------------------- + +This has been replaced by hook_entity_diff() as of Diff 7.x-3.x. + +3) Field diffs are handled independently by Diff and the field module +--------------------------------------------------------------------- + +Field modules SHOULD NOT implement hook_entity_diff(). + +This is complicated and costly in terms of performance. + +Two new field callbacks are defined to handle these. + + a) MODULE_field_diff_view_prepare() + + Optional: If you need to load data, use MODULE_field_diff_view_prepare(). + + b) MODULE_field_diff_view() + + Recommended: You should implement this to generate the compared data. + +If there is no corresponding hook for a field, the field comparison will try +to guess the value using $item['safe_value'] or $item['value'] properties. + +If you need to make this configurable, there are two additional hooks: + + c) MODULE_field_diff_default_options($field_type) + + You should define any additioal settings here. This shares a global namespace + of the diff module, so you can overwrite core Diff settings here too. + + In saying that, take care not to accidentially do this. + + d) MODULE_field_diff_options_form($field_type, $settings) + + This is where you insert Form API elements to configure your option settings. + +4) Field diffs are now configurable +----------------------------------- + +Each field type defined by core have configurable settings to control the +rendering of the comparison. + + a) Global configuration + + An administration page has been added to handle field type default settings. + + This is the preferred way to configure field settings are these are global to + all fields of this type. + + b) View mode display options + + The display "Diff comparison" is used to control the fields that are displayed + when comparing different revisions. + + The following is a walk-through on how you would configure the Basic page + (page) content types field configuration. + + - Enable "Diff comparison" custom view mode + + Navigate to admin/structure/types/manage/page/display and look at the + Custom Display Settings for this view mode. Check and save. + + - Configure the display + + After Saving this page, a new tab appears "Diff comparison", click this or + navigate directly to admin/structure/types/manage/page/display/diff_standard + + - You can hide or show the fields that you want to display when doing + comparisons. + - If the field has no inbuilt diff support, then the renderred field items + will be compared. + +5) Standard comparison preview / Inline diff view setting +--------------------------------------------------------- + +You can set the view modes used to compare the rendered node. This can be found +in the Diff settings in the Content Type settings page. + +6) Optional CSS and new Boxes styles +------------------------------------ + +This takes the styles from WikiPedia to really spice up the diff page. + +7) Optional JScript extras +-------------------------- + +This spices up the revision checkboxes on the revisions page. + +8) Simple past revision token support +------------------------------------- + +Use-case, email notifications when content has changes. If these support tokens, +then you can embed Diffs into these emails. + +9) Extensive string review +-------------------------- +See http://drupal.org/node/1785742 + + +10) Inline block settings changes +--------------------------------- +The inline block settings are now in the block configuration page. + +11) And much more... +-------------------- + +The complete change log follows: + +Diff 7.x-2.x + o #888680 by Deciphered, Alan D.: Allow modules to interact via drupal_alter() + o #1280892 by Alan D., crea: Diff should track the variables that it defines + o #1304658 by Alan D., kari.kaariainen: Remove links and comments from the comparison preview + o #1122206 by binford2k, Alan D.: Notices thrown by DiffEngine::process_chunk() + o #1175064 by zilverdistel, Alan D.: Provide variables for leading and trailing context + o #1673864 by Alan D.: Allow users to bypass the admin theme when viewing comparisons + o #1673876 by Alan D.: Use Drupal autoloading for classes + o #1673856 by Alan D.: Use hook_form_BASE_FORM_ID_alter() rather than hook_form_alter() + o #1673856 by Alan D.: Normalise line endings + o #114308 by Alan D.: add jQuery for hiding radios that shouldn't show diffs + o #1688840 by Alan D.: Enable new JScript behaviour by default + o #372957 by erykmynn, JuliaKM, lsrzj, andrew_rs, alexpott, et al: HTML Strip for Diff, WYSIWYG Friendly + (This was refactored in the 7.x-3.x branch from the commited 7.x-2.x code) + o #521212 by Alan D., blakehall: Make diff comparison page themable + o #1671484 by Alan D.: Show number of lines changed on revisions page + o #114699 by smokris, Alan D.: Diff module should support Token + o #372957 by c31ck: display either Hide or Show based on what clicking it will do at any time (HTML Strip for Diff) + This was altered for the 7.x-3.x branch. + o #1807510 & #1825202: Simplify Diff administration + o #1812162 by mitchell, Alan D.: 'Highlight changes' block appears on edit form + + Node to Entity changes + ---------------------- + These are roughly tracked in the meta issue #1365750 Generalize API and Integrate with core field types + + o (no issue) by Alan D.: Use entity specific system variables. + o (no issue) by Alan D.: View mode code, new hooks, new API. Massive patch! + + Resolves: + o #248778: Taxonomy diff + o #1550698: Diff of "select from list" fields shows change in key, not change in value + o #1458814: File (and image) field support + o #1418760: Optional setting to honour the display settings + o #1347316: Selectable view mode for inline diffs and "Current revision" display view mode + o #1458906: Improve performances (of existing 7.x-2.x field rendering) + o #1424162: Diff in Taxonomy term description + o #1211282: Image diff support + +The following patches will be posted in the corresponding project queues once +the 7.x-3.x branch is released: + o #1595702 by Alan D., mbilbille: Support of field collection module + o #1350604 by Alan D., johaziel: Datetime diff + o (no issue) by Alan D.: Email field Diff support + o (no issue) by Alan D.: Countries Diff support + o (no issue) by Alan D.: Name field Diff support + o (no issue) by Alan D.: Link field Diff support diff --git a/profiles/wcm_base/modules/contrib/diff/DiffEngine.php b/profiles/wcm_base/modules/contrib/diff/DiffEngine.php new file mode 100644 index 00000000..12366107 --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/DiffEngine.php @@ -0,0 +1,1349 @@ +<?php + +/** + * @file + * A PHP diff engine for phpwiki. (Taken from phpwiki-1.3.3) + * + * Copyright (C) 2000, 2001 Geoffrey T. Dairiki <dairiki@dairiki.org> + * You may copy this code freely under the conditions of the GPL. + */ + +define('USE_ASSERTS', FALSE); + +/** + * @todo document + * @private + * @subpackage DifferenceEngine + */ +class _DiffOp { + var $type; + var $orig; + var $closing; + + function reverse() { + trigger_error('pure virtual', E_USER_ERROR); + } + + function norig() { + return $this->orig ? sizeof($this->orig) : 0; + } + + function nclosing() { + return $this->closing ? sizeof($this->closing) : 0; + } +} + +/** + * @todo document + * @private + * @subpackage DifferenceEngine + */ +class _DiffOp_Copy extends _DiffOp { + var $type = 'copy'; + + function _DiffOp_Copy($orig, $closing = FALSE) { + if (!is_array($closing)) { + $closing = $orig; + } + $this->orig = $orig; + $this->closing = $closing; + } + + function reverse() { + return new _DiffOp_Copy($this->closing, $this->orig); + } +} + +/** + * @todo document + * @private + * @subpackage DifferenceEngine + */ +class _DiffOp_Delete extends _DiffOp { + var $type = 'delete'; + + function _DiffOp_Delete($lines) { + $this->orig = $lines; + $this->closing = FALSE; + } + + function reverse() { + return new _DiffOp_Add($this->orig); + } +} + +/** + * @todo document + * @private + * @subpackage DifferenceEngine + */ +class _DiffOp_Add extends _DiffOp { + var $type = 'add'; + + function _DiffOp_Add($lines) { + $this->closing = $lines; + $this->orig = FALSE; + } + + function reverse() { + return new _DiffOp_Delete($this->closing); + } +} + +/** + * @todo document + * @private + * @subpackage DifferenceEngine + */ +class _DiffOp_Change extends _DiffOp { + var $type = 'change'; + + function _DiffOp_Change($orig, $closing) { + $this->orig = $orig; + $this->closing = $closing; + } + + function reverse() { + return new _DiffOp_Change($this->closing, $this->orig); + } +} + + +/** + * Class used internally by Diff to actually compute the diffs. + * + * The algorithm used here is mostly lifted from the perl module + * Algorithm::Diff (version 1.06) by Ned Konz, which is available at: + * http://www.perl.com/CPAN/authors/id/N/NE/NEDKONZ/Algorithm-Diff-1.06.zip + * + * More ideas are taken from: + * http://www.ics.uci.edu/~eppstein/161/960229.html + * + * Some ideas are (and a bit of code) are from from analyze.c, from GNU + * diffutils-2.7, which can be found at: + * ftp://gnudist.gnu.org/pub/gnu/diffutils/diffutils-2.7.tar.gz + * + * closingly, some ideas (subdivision by NCHUNKS > 2, and some optimizations) + * are my own. + * + * Line length limits for robustness added by Tim Starling, 2005-08-31 + * + * @author Geoffrey T. Dairiki, Tim Starling + * @private + * @subpackage DifferenceEngine + */ +class _DiffEngine { + function MAX_XREF_LENGTH() { + return 10000; + } + + function diff($from_lines, $to_lines) { + + $n_from = sizeof($from_lines); + $n_to = sizeof($to_lines); + + $this->xchanged = $this->ychanged = array(); + $this->xv = $this->yv = array(); + $this->xind = $this->yind = array(); + unset($this->seq); + unset($this->in_seq); + unset($this->lcs); + + // Skip leading common lines. + for ($skip = 0; $skip < $n_from && $skip < $n_to; $skip++) { + if ($from_lines[$skip] !== $to_lines[$skip]) { + break; + } + $this->xchanged[$skip] = $this->ychanged[$skip] = FALSE; + } + // Skip trailing common lines. + $xi = $n_from; + $yi = $n_to; + for ($endskip = 0; --$xi > $skip && --$yi > $skip; $endskip++) { + if ($from_lines[$xi] !== $to_lines[$yi]) { + break; + } + $this->xchanged[$xi] = $this->ychanged[$yi] = FALSE; + } + + // Ignore lines which do not exist in both files. + for ($xi = $skip; $xi < $n_from - $endskip; $xi++) { + $xhash[$this->_line_hash($from_lines[$xi])] = 1; + } + + for ($yi = $skip; $yi < $n_to - $endskip; $yi++) { + $line = $to_lines[$yi]; + if ($this->ychanged[$yi] = empty($xhash[$this->_line_hash($line)])) { + continue; + } + $yhash[$this->_line_hash($line)] = 1; + $this->yv[] = $line; + $this->yind[] = $yi; + } + for ($xi = $skip; $xi < $n_from - $endskip; $xi++) { + $line = $from_lines[$xi]; + if ($this->xchanged[$xi] = empty($yhash[$this->_line_hash($line)])) { + continue; + } + $this->xv[] = $line; + $this->xind[] = $xi; + } + + // Find the LCS. + $this->_compareseq(0, sizeof($this->xv), 0, sizeof($this->yv)); + + // Merge edits when possible + $this->_shift_boundaries($from_lines, $this->xchanged, $this->ychanged); + $this->_shift_boundaries($to_lines, $this->ychanged, $this->xchanged); + + // Compute the edit operations. + $edits = array(); + $xi = $yi = 0; + while ($xi < $n_from || $yi < $n_to) { + USE_ASSERTS && assert($yi < $n_to || $this->xchanged[$xi]); + USE_ASSERTS && assert($xi < $n_from || $this->ychanged[$yi]); + + // Skip matching "snake". + $copy = array(); + while ( $xi < $n_from && $yi < $n_to && !$this->xchanged[$xi] && !$this->ychanged[$yi]) { + $copy[] = $from_lines[$xi++]; + ++$yi; + } + if ($copy) { + $edits[] = new _DiffOp_Copy($copy); + } + // Find deletes & adds. + $delete = array(); + while ($xi < $n_from && $this->xchanged[$xi]) { + $delete[] = $from_lines[$xi++]; + } + $add = array(); + while ($yi < $n_to && $this->ychanged[$yi]) { + $add[] = $to_lines[$yi++]; + } + if ($delete && $add) { + $edits[] = new _DiffOp_Change($delete, $add); + } + elseif ($delete) { + $edits[] = new _DiffOp_Delete($delete); + } + elseif ($add) { + $edits[] = new _DiffOp_Add($add); + } + } + return $edits; + } + + /** + * Returns the whole line if it's small enough, or the MD5 hash otherwise. + */ + function _line_hash($line) { + if (drupal_strlen($line) > $this->MAX_XREF_LENGTH()) { + return md5($line); + } + else { + return $line; + } + } + + + /** + * Divide the Largest Common Subsequence (LCS) of the sequences + * [XOFF, XLIM) and [YOFF, YLIM) into NCHUNKS approximately equally + * sized segments. + * + * Returns (LCS, PTS). LCS is the length of the LCS. PTS is an + * array of NCHUNKS+1 (X, Y) indexes giving the diving points between + * sub sequences. The first sub-sequence is contained in [X0, X1), + * [Y0, Y1), the second in [X1, X2), [Y1, Y2) and so on. Note + * that (X0, Y0) == (XOFF, YOFF) and + * (X[NCHUNKS], Y[NCHUNKS]) == (XLIM, YLIM). + * + * This function assumes that the first lines of the specified portions + * of the two files do not match, and likewise that the last lines do not + * match. The caller must trim matching lines from the beginning and end + * of the portions it is going to specify. + */ + function _diag($xoff, $xlim, $yoff, $ylim, $nchunks) { + $flip = FALSE; + + if ($xlim - $xoff > $ylim - $yoff) { + // Things seems faster (I'm not sure I understand why) + // when the shortest sequence in X. + $flip = TRUE; + list($xoff, $xlim, $yoff, $ylim) = array($yoff, $ylim, $xoff, $xlim); + } + + if ($flip) { + for ($i = $ylim - 1; $i >= $yoff; $i--) { + $ymatches[$this->xv[$i]][] = $i; + } + } + else { + for ($i = $ylim - 1; $i >= $yoff; $i--) { + $ymatches[$this->yv[$i]][] = $i; + } + } + $this->lcs = 0; + $this->seq[0]= $yoff - 1; + $this->in_seq = array(); + $ymids[0] = array(); + + $numer = $xlim - $xoff + $nchunks - 1; + $x = $xoff; + for ($chunk = 0; $chunk < $nchunks; $chunk++) { + if ($chunk > 0) { + for ($i = 0; $i <= $this->lcs; $i++) { + $ymids[$i][$chunk-1] = $this->seq[$i]; + } + } + + $x1 = $xoff + (int)(($numer + ($xlim-$xoff)*$chunk) / $nchunks); + for ( ; $x < $x1; $x++) { + $line = $flip ? $this->yv[$x] : $this->xv[$x]; + if (empty($ymatches[$line])) { + continue; + } + $matches = $ymatches[$line]; + reset($matches); + while (list ($junk, $y) = each($matches)) { + if (empty($this->in_seq[$y])) { + $k = $this->_lcs_pos($y); + USE_ASSERTS && assert($k > 0); + $ymids[$k] = $ymids[$k-1]; + break; + } + } + while (list ($junk, $y) = each($matches)) { + if ($y > $this->seq[$k-1]) { + USE_ASSERTS && assert($y < $this->seq[$k]); + // Optimization: this is a common case: + // next match is just replacing previous match. + $this->in_seq[$this->seq[$k]] = FALSE; + $this->seq[$k] = $y; + $this->in_seq[$y] = 1; + } + elseif (empty($this->in_seq[$y])) { + $k = $this->_lcs_pos($y); + USE_ASSERTS && assert($k > 0); + $ymids[$k] = $ymids[$k-1]; + } + } + } + } + + $seps[] = $flip ? array($yoff, $xoff) : array($xoff, $yoff); + $ymid = $ymids[$this->lcs]; + for ($n = 0; $n < $nchunks - 1; $n++) { + $x1 = $xoff + (int)(($numer + ($xlim - $xoff) * $n) / $nchunks); + $y1 = $ymid[$n] + 1; + $seps[] = $flip ? array($y1, $x1) : array($x1, $y1); + } + $seps[] = $flip ? array($ylim, $xlim) : array($xlim, $ylim); + + return array($this->lcs, $seps); + } + + function _lcs_pos($ypos) { + + $end = $this->lcs; + if ($end == 0 || $ypos > $this->seq[$end]) { + $this->seq[++$this->lcs] = $ypos; + $this->in_seq[$ypos] = 1; + return $this->lcs; + } + + $beg = 1; + while ($beg < $end) { + $mid = (int)(($beg + $end) / 2); + if ($ypos > $this->seq[$mid]) { + $beg = $mid + 1; + } + else { + $end = $mid; + } + } + + USE_ASSERTS && assert($ypos != $this->seq[$end]); + + $this->in_seq[$this->seq[$end]] = FALSE; + $this->seq[$end] = $ypos; + $this->in_seq[$ypos] = 1; + return $end; + } + + /** + * Find LCS of two sequences. + * + * The results are recorded in the vectors $this->{x,y}changed[], by + * storing a 1 in the element for each line that is an insertion + * or deletion (ie. is not in the LCS). + * + * The subsequence of file 0 is [XOFF, XLIM) and likewise for file 1. + * + * Note that XLIM, YLIM are exclusive bounds. + * All line numbers are origin-0 and discarded lines are not counted. + */ + function _compareseq($xoff, $xlim, $yoff, $ylim) { + + // Slide down the bottom initial diagonal. + while ($xoff < $xlim && $yoff < $ylim && $this->xv[$xoff] == $this->yv[$yoff]) { + ++$xoff; + ++$yoff; + } + + // Slide up the top initial diagonal. + while ($xlim > $xoff && $ylim > $yoff && $this->xv[$xlim - 1] == $this->yv[$ylim - 1]) { + --$xlim; + --$ylim; + } + + if ($xoff == $xlim || $yoff == $ylim) { + $lcs = 0; + } + else { + // This is ad hoc but seems to work well. + //$nchunks = sqrt(min($xlim - $xoff, $ylim - $yoff) / 2.5); + //$nchunks = max(2, min(8, (int)$nchunks)); + $nchunks = min(7, $xlim - $xoff, $ylim - $yoff) + 1; + list($lcs, $seps) + = $this->_diag($xoff, $xlim, $yoff, $ylim, $nchunks); + } + + if ($lcs == 0) { + // X and Y sequences have no common subsequence: + // mark all changed. + while ($yoff < $ylim) { + $this->ychanged[$this->yind[$yoff++]] = 1; + } + while ($xoff < $xlim) { + $this->xchanged[$this->xind[$xoff++]] = 1; + } + } + else { + // Use the partitions to split this problem into subproblems. + reset($seps); + $pt1 = $seps[0]; + while ($pt2 = next($seps)) { + $this->_compareseq ($pt1[0], $pt2[0], $pt1[1], $pt2[1]); + $pt1 = $pt2; + } + } + } + + /** + * Adjust inserts/deletes of identical lines to join changes + * as much as possible. + * + * We do something when a run of changed lines include a + * line at one end and has an excluded, identical line at the other. + * We are free to choose which identical line is included. + * `compareseq' usually chooses the one at the beginning, + * but usually it is cleaner to consider the following identical line + * to be the "change". + * + * This is extracted verbatim from analyze.c (GNU diffutils-2.7). + */ + function _shift_boundaries($lines, &$changed, $other_changed) { + $i = 0; + $j = 0; + + USE_ASSERTS && assert('sizeof($lines) == sizeof($changed)'); + $len = sizeof($lines); + $other_len = sizeof($other_changed); + + while (1) { + /* + * Scan forwards to find beginning of another run of changes. + * Also keep track of the corresponding point in the other file. + * + * Throughout this code, $i and $j are adjusted together so that + * the first $i elements of $changed and the first $j elements + * of $other_changed both contain the same number of zeros + * (unchanged lines). + * Furthermore, $j is always kept so that $j == $other_len or + * $other_changed[$j] == FALSE. + */ + while ($j < $other_len && $other_changed[$j]) { + $j++; + } + while ($i < $len && ! $changed[$i]) { + USE_ASSERTS && assert('$j < $other_len && ! $other_changed[$j]'); + $i++; + $j++; + while ($j < $other_len && $other_changed[$j]) { + $j++; + } + } + + if ($i == $len) { + break; + } + $start = $i; + + // Find the end of this run of changes. + while (++$i < $len && $changed[$i]) { + continue; + } + + do { + /* + * Record the length of this run of changes, so that + * we can later determine whether the run has grown. + */ + $runlength = $i - $start; + + /* + * Move the changed region back, so long as the + * previous unchanged line matches the last changed one. + * This merges with previous changed regions. + */ + while ($start > 0 && $lines[$start - 1] == $lines[$i - 1]) { + $changed[--$start] = 1; + $changed[--$i] = FALSE; + while ($start > 0 && $changed[$start - 1]) { + $start--; + } + USE_ASSERTS && assert('$j > 0'); + while ($other_changed[--$j]) { + continue; + } + USE_ASSERTS && assert('$j >= 0 && !$other_changed[$j]'); + } + + /* + * Set CORRESPONDING to the end of the changed run, at the last + * point where it corresponds to a changed run in the other file. + * CORRESPONDING == LEN means no such point has been found. + */ + $corresponding = $j < $other_len ? $i : $len; + + /* + * Move the changed region forward, so long as the + * first changed line matches the following unchanged one. + * This merges with following changed regions. + * Do this second, so that if there are no merges, + * the changed region is moved forward as far as possible. + */ + while ($i < $len && $lines[$start] == $lines[$i]) { + $changed[$start++] = FALSE; + $changed[$i++] = 1; + while ($i < $len && $changed[$i]) { + $i++; + } + USE_ASSERTS && assert('$j < $other_len && ! $other_changed[$j]'); + $j++; + if ($j < $other_len && $other_changed[$j]) { + $corresponding = $i; + while ($j < $other_len && $other_changed[$j]) { + $j++; + } + } + } + } while ($runlength != $i - $start); + + /* + * If possible, move the fully-merged run of changes + * back to a corresponding run in the other file. + */ + while ($corresponding < $i) { + $changed[--$start] = 1; + $changed[--$i] = 0; + USE_ASSERTS && assert('$j > 0'); + while ($other_changed[--$j]) { + continue; + } + USE_ASSERTS && assert('$j >= 0 && !$other_changed[$j]'); + } + } + } +} + +/** + * Class representing a 'diff' between two sequences of strings. + * @todo document + * @private + * @subpackage DifferenceEngine + */ +class Diff { + var $edits; + + /** + * Constructor. + * Computes diff between sequences of strings. + * + * @param $from_lines array An array of strings. + * (Typically these are lines from a file.) + * @param $to_lines array An array of strings. + */ + function Diff($from_lines, $to_lines) { + $eng = new _DiffEngine; + $this->edits = $eng->diff($from_lines, $to_lines); + //$this->_check($from_lines, $to_lines); + } + + /** + * Compute reversed Diff. + * + * SYNOPSIS: + * + * $diff = new Diff($lines1, $lines2); + * $rev = $diff->reverse(); + * @return object A Diff object representing the inverse of the + * original diff. + */ + function reverse() { + $rev = $this; + $rev->edits = array(); + foreach ($this->edits as $edit) { + $rev->edits[] = $edit->reverse(); + } + return $rev; + } + + /** + * Check for empty diff. + * + * @return bool True iff two sequences were identical. + */ + function isEmpty() { + foreach ($this->edits as $edit) { + if ($edit->type != 'copy') { + return FALSE; + } + } + return TRUE; + } + + /** + * Compute the length of the Longest Common Subsequence (LCS). + * + * This is mostly for diagnostic purposed. + * + * @return int The length of the LCS. + */ + function lcs() { + $lcs = 0; + foreach ($this->edits as $edit) { + if ($edit->type == 'copy') { + $lcs += sizeof($edit->orig); + } + } + return $lcs; + } + + /** + * Get the original set of lines. + * + * This reconstructs the $from_lines parameter passed to the + * constructor. + * + * @return array The original sequence of strings. + */ + function orig() { + $lines = array(); + + foreach ($this->edits as $edit) { + if ($edit->orig) { + array_splice($lines, sizeof($lines), 0, $edit->orig); + } + } + return $lines; + } + + /** + * Get the closing set of lines. + * + * This reconstructs the $to_lines parameter passed to the + * constructor. + * + * @return array The sequence of strings. + */ + function closing() { + $lines = array(); + + foreach ($this->edits as $edit) { + if ($edit->closing) { + array_splice($lines, sizeof($lines), 0, $edit->closing); + } + } + return $lines; + } + + /** + * Check a Diff for validity. + * + * This is here only for debugging purposes. + */ + function _check($from_lines, $to_lines) { + if (serialize($from_lines) != serialize($this->orig())) { + trigger_error("Reconstructed original doesn't match", E_USER_ERROR); + } + if (serialize($to_lines) != serialize($this->closing())) { + trigger_error("Reconstructed closing doesn't match", E_USER_ERROR); + } + + $rev = $this->reverse(); + if (serialize($to_lines) != serialize($rev->orig())) { + trigger_error("Reversed original doesn't match", E_USER_ERROR); + } + if (serialize($from_lines) != serialize($rev->closing())) { + trigger_error("Reversed closing doesn't match", E_USER_ERROR); + } + + + $prevtype = 'none'; + foreach ($this->edits as $edit) { + if ( $prevtype == $edit->type ) { + trigger_error("Edit sequence is non-optimal", E_USER_ERROR); + } + $prevtype = $edit->type; + } + + $lcs = $this->lcs(); + trigger_error('Diff okay: LCS = ' . $lcs, E_USER_NOTICE); + } +} + +/** + * FIXME: bad name. + * @todo document + * @private + * @subpackage DifferenceEngine + */ +class MappedDiff extends Diff { + /** + * Constructor. + * + * Computes diff between sequences of strings. + * + * This can be used to compute things like + * case-insensitve diffs, or diffs which ignore + * changes in white-space. + * + * @param $from_lines array An array of strings. + * (Typically these are lines from a file.) + * + * @param $to_lines array An array of strings. + * + * @param $mapped_from_lines array This array should + * have the same size number of elements as $from_lines. + * The elements in $mapped_from_lines and + * $mapped_to_lines are what is actually compared + * when computing the diff. + * + * @param $mapped_to_lines array This array should + * have the same number of elements as $to_lines. + */ + function MappedDiff($from_lines, $to_lines, $mapped_from_lines, $mapped_to_lines) { + + assert(sizeof($from_lines) == sizeof($mapped_from_lines)); + assert(sizeof($to_lines) == sizeof($mapped_to_lines)); + + $this->Diff($mapped_from_lines, $mapped_to_lines); + + $xi = $yi = 0; + for ($i = 0; $i < sizeof($this->edits); $i++) { + $orig = &$this->edits[$i]->orig; + if (is_array($orig)) { + $orig = array_slice($from_lines, $xi, sizeof($orig)); + $xi += sizeof($orig); + } + + $closing = &$this->edits[$i]->closing; + if (is_array($closing)) { + $closing = array_slice($to_lines, $yi, sizeof($closing)); + $yi += sizeof($closing); + } + } + } +} + +/** + * A class to format Diffs + * + * This class formats the diff in classic diff format. + * It is intended that this class be customized via inheritance, + * to obtain fancier outputs. + * @todo document + * @private + * @subpackage DifferenceEngine + */ +class DiffFormatter { + /** + * Should a block header be shown? + */ + var $show_header = TRUE; + + /** + * Number of leading context "lines" to preserve. + * + * This should be left at zero for this class, but subclasses + * may want to set this to other values. + */ + var $leading_context_lines = 0; + + /** + * Number of trailing context "lines" to preserve. + * + * This should be left at zero for this class, but subclasses + * may want to set this to other values. + */ + var $trailing_context_lines = 0; + + /** + * Format a diff. + * + * @param $diff object A Diff object. + * @return string The formatted output. + */ + function format($diff) { + $xi = $yi = 1; + $block = FALSE; + $context = array(); + + $nlead = $this->leading_context_lines; + $ntrail = $this->trailing_context_lines; + + $this->_start_diff(); + + foreach ($diff->edits as $edit) { + if ($edit->type == 'copy') { + if (is_array($block)) { + if (sizeof($edit->orig) <= $nlead + $ntrail) { + $block[] = $edit; + } + else { + if ($ntrail) { + $context = array_slice($edit->orig, 0, $ntrail); + $block[] = new _DiffOp_Copy($context); + } + $this->_block($x0, $ntrail + $xi - $x0, $y0, $ntrail + $yi - $y0, $block); + $block = FALSE; + } + } + $context = $edit->orig; + } + else { + if (! is_array($block)) { + $context = array_slice($context, sizeof($context) - $nlead); + $x0 = $xi - sizeof($context); + $y0 = $yi - sizeof($context); + $block = array(); + if ($context) { + $block[] = new _DiffOp_Copy($context); + } + } + $block[] = $edit; + } + + if ($edit->orig) { + $xi += sizeof($edit->orig); + } + if ($edit->closing) { + $yi += sizeof($edit->closing); + } + } + + if (is_array($block)) { + $this->_block($x0, $xi - $x0, $y0, $yi - $y0, $block); + } + $end = $this->_end_diff(); + + if (!empty($xi)) { + $this->line_stats['counter']['x'] += $xi; + } + if (!empty($yi)) { + $this->line_stats['counter']['y'] += $yi; + } + + return $end; + } + + function _block($xbeg, $xlen, $ybeg, $ylen, &$edits) { + $this->_start_block($this->_block_header($xbeg, $xlen, $ybeg, $ylen)); + foreach ($edits as $edit) { + if ($edit->type == 'copy') { + $this->_context($edit->orig); + } + elseif ($edit->type == 'add') { + $this->_added($edit->closing); + } + elseif ($edit->type == 'delete') { + $this->_deleted($edit->orig); + } + elseif ($edit->type == 'change') { + $this->_changed($edit->orig, $edit->closing); + } + else { + trigger_error('Unknown edit type', E_USER_ERROR); + } + } + $this->_end_block(); + } + + function _start_diff() { + ob_start(); + } + + function _end_diff() { + $val = ob_get_contents(); + ob_end_clean(); + return $val; + } + + function _block_header($xbeg, $xlen, $ybeg, $ylen) { + if ($xlen > 1) { + $xbeg .= "," . ($xbeg + $xlen - 1); + } + if ($ylen > 1) { + $ybeg .= "," . ($ybeg + $ylen - 1); + } + + return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg; + } + + function _start_block($header) { + if ($this->show_header) { + echo $header . "\n"; + } + } + + function _end_block() { + } + + function _lines($lines, $prefix = ' ') { + foreach ($lines as $line) { + echo "$prefix $line\n"; + } + } + + function _context($lines) { + $this->_lines($lines); + } + + function _added($lines) { + $this->_lines($lines, '>'); + } + function _deleted($lines) { + $this->_lines($lines, '<'); + } + + function _changed($orig, $closing) { + $this->_deleted($orig); + echo "---\n"; + $this->_added($closing); + } +} + + +/** + * Additions by Axel Boldt follow, partly taken from diff.php, phpwiki-1.3.3 + * + */ + +define('NBSP', ' '); // iso-8859-x non-breaking space. + +/** + * @todo document + * @private + * @subpackage DifferenceEngine + */ +class _HWLDF_WordAccumulator { + function _HWLDF_WordAccumulator() { + $this->_lines = array(); + $this->_line = ''; + $this->_group = ''; + $this->_tag = ''; + } + + function _flushGroup($new_tag) { + if ($this->_group !== '') { + if ($this->_tag == 'mark') { + $this->_line .= '<span class="diffchange">' . check_plain($this->_group) . '</span>'; + } + else { + $this->_line .= check_plain($this->_group); + } + } + $this->_group = ''; + $this->_tag = $new_tag; + } + + function _flushLine($new_tag) { + $this->_flushGroup($new_tag); + if ($this->_line != '') { + array_push($this->_lines, $this->_line); + } + else { + // make empty lines visible by inserting an NBSP + array_push($this->_lines, NBSP); + } + $this->_line = ''; + } + + function addWords($words, $tag = '') { + if ($tag != $this->_tag) { + $this->_flushGroup($tag); + } + foreach ($words as $word) { + // new-line should only come as first char of word. + if ($word == '') { + continue; + } + if ($word[0] == "\n") { + $this->_flushLine($tag); + $word = drupal_substr($word, 1); + } + assert(!strstr($word, "\n")); + $this->_group .= $word; + } + } + + function getLines() { + $this->_flushLine('~done'); + return $this->_lines; + } +} + +/** + * @todo document + * @private + * @subpackage DifferenceEngine + */ +class WordLevelDiff extends MappedDiff { + function MAX_LINE_LENGTH() { + return 10000; + } + + function WordLevelDiff($orig_lines, $closing_lines) { + list($orig_words, $orig_stripped) = $this->_split($orig_lines); + list($closing_words, $closing_stripped) = $this->_split($closing_lines); + + $this->MappedDiff($orig_words, $closing_words, $orig_stripped, $closing_stripped); + } + + function _split($lines) { + $words = array(); + $stripped = array(); + $first = TRUE; + foreach ($lines as $line) { + // If the line is too long, just pretend the entire line is one big word + // This prevents resource exhaustion problems + if ( $first ) { + $first = FALSE; + } + else { + $words[] = "\n"; + $stripped[] = "\n"; + } + if ( drupal_strlen( $line ) > $this->MAX_LINE_LENGTH() ) { + $words[] = $line; + $stripped[] = $line; + } + else { + if (preg_match_all('/ ( [^\S\n]+ | [0-9_A-Za-z\x80-\xff]+ | . ) (?: (?!< \n) [^\S\n])? /xs', $line, $m)) { + $words = array_merge($words, $m[0]); + $stripped = array_merge($stripped, $m[1]); + } + } + } + return array($words, $stripped); + } + + function orig() { + $orig = new _HWLDF_WordAccumulator; + + foreach ($this->edits as $edit) { + if ($edit->type == 'copy') { + $orig->addWords($edit->orig); + } + elseif ($edit->orig) { + $orig->addWords($edit->orig, 'mark'); + } + } + $lines = $orig->getLines(); + return $lines; + } + + function closing() { + $closing = new _HWLDF_WordAccumulator; + + foreach ($this->edits as $edit) { + if ($edit->type == 'copy') { + $closing->addWords($edit->closing); + } + elseif ($edit->closing) { + $closing->addWords($edit->closing, 'mark'); + } + } + $lines = $closing->getLines(); + return $lines; + } +} + +/** + * Diff formatter which uses Drupal theme functions. + * @private + * @subpackage DifferenceEngine + */ +class DrupalDiffFormatter extends DiffFormatter { + + var $rows; + var $line_stats = array( + 'counter' => array('x' => 0, 'y' => 0), + 'offset' => array('x' => 0, 'y' => 0), + ); + + function DrupalDiffFormatter() { + $this->leading_context_lines = variable_get('diff_context_lines_leading', 2); + $this->trailing_context_lines = variable_get('diff_context_lines_trailing', 2); + } + + function _start_diff() { + $this->rows = array(); + } + + function _end_diff() { + return $this->rows; + } + + function _block_header($xbeg, $xlen, $ybeg, $ylen) { + return array( + array( + 'data' => theme('diff_header_line', array('lineno' => $xbeg + $this->line_stats['offset']['x'])), + 'colspan' => 2, + ), + array( + 'data' => theme('diff_header_line', array('lineno' => $ybeg + $this->line_stats['offset']['y'])), + 'colspan' => 2, + ) + ); + } + + function _start_block($header) { + if ($this->show_header) { + $this->rows[] = $header; + } + } + + function _end_block() { + } + + function _lines($lines, $prefix=' ', $color='white') { + } + + /** + * Note: you should HTML-escape parameter before calling this. + */ + function addedLine($line) { + return array( + array( + 'data' => '+', + 'class' => 'diff-marker', + ), + array( + 'data' => theme('diff_content_line', array('line' => $line)), + 'class' => 'diff-context diff-addedline', + ) + ); + } + + /** + * Note: you should HTML-escape parameter before calling this. + */ + function deletedLine($line) { + return array( + array( + 'data' => '-', + 'class' => 'diff-marker', + ), + array( + 'data' => theme('diff_content_line', array('line' => $line)), + 'class' => 'diff-context diff-deletedline', + ) + ); + } + + /** + * Note: you should HTML-escape parameter before calling this. + */ + function contextLine($line) { + return array( + ' ', + array( + 'data' => theme('diff_content_line', array('line' => $line)), + 'class' => 'diff-context', + ) + ); + } + + function emptyLine() { + return array( + ' ', + theme('diff_empty_line', array('line' => ' ')), + ); + } + + function _added($lines) { + foreach ($lines as $line) { + $this->rows[] = array_merge($this->emptyLine(), $this->addedLine(check_plain($line))); + } + } + + function _deleted($lines) { + foreach ($lines as $line) { + $this->rows[] = array_merge($this->deletedLine(check_plain($line)), $this->emptyLine()); + } + } + + function _context($lines) { + foreach ($lines as $line) { + $this->rows[] = array_merge($this->contextLine(check_plain($line)), $this->contextLine(check_plain($line))); + } + } + + function _changed($orig, $closing) { + $diff = new WordLevelDiff($orig, $closing); + $del = $diff->orig(); + $add = $diff->closing(); + + // Notice that WordLevelDiff returns HTML-escaped output. + // Hence, we will be calling addedLine/deletedLine without HTML-escaping. + + while ($line = array_shift($del)) { + $aline = array_shift( $add ); + $this->rows[] = array_merge($this->deletedLine($line), isset($aline) ? $this->addedLine($aline) : $this->emptyLine()); + } + foreach ($add as $line) { // If any leftovers + $this->rows[] = array_merge($this->emptyLine(), $this->addedLine($line)); + } + } +} + +/** + * Drupal inline Diff formatter. + * @private + * @subpackage DifferenceEngine + */ +class DrupalDiffInline { + var $a; + var $b; + + /** + * Constructor. + */ + function __construct($a, $b) { + $this->a = $a; + $this->b = $b; + } + + /** + * Render differences inline using HTML markup. + */ + function render() { + $a = preg_split('/(<[^>]+?>| )/', $this->a, -1, PREG_SPLIT_DELIM_CAPTURE); + $b = preg_split('/(<[^>]+?>| )/', $this->b, -1, PREG_SPLIT_DELIM_CAPTURE); + $diff = new Diff($a, $b); + $diff->edits = $this->process_edits($diff->edits); + + // Assemble highlighted output + $output = ''; + foreach ($diff->edits as $chunk) { + switch ($chunk->type) { + case 'copy': + $output .= implode('', $chunk->closing); + break; + case 'delete': + foreach ($chunk->orig as $i => $piece) { + if (strpos($piece, '<') === 0 && drupal_substr($piece, drupal_strlen($piece) - 1) === '>') { + $output .= $piece; + } + else { + $output .= theme('diff_inline_chunk', array('text' => $piece, 'type' => $chunk->type)); + } + } + break; + default: + $chunk->closing = $this->process_chunk($chunk->closing); + foreach ($chunk->closing as $i => $piece) { + if ($piece === ' ' || (strpos($piece, '<') === 0 && drupal_substr($piece, drupal_strlen($piece) - 1) === '>' && drupal_strtolower(drupal_substr($piece, 1, 3)) != 'img')) { + $output .= $piece; + } + else { + $output .= theme('diff_inline_chunk', array('text' => $piece, 'type' => $chunk->type)); + } + } + break; + } + } + return $output; + } + + /** + * Merge chunk segments between tag delimiters. + */ + function process_chunk($chunk) { + $processed = array(); + $j = 0; + foreach ($chunk as $i => $piece) { + $next = isset($chunk[$i+1]) ? $chunk[$i+1] : NULL; + if (!isset($processed[$j])) { + $processed[$j] = ''; + } + if (strpos($piece, '<') === 0 && drupal_substr($piece, drupal_strlen($piece) - 1) === '>') { + $processed[$j] = $piece; + $j++; + } + elseif (isset($next) && strpos($next, '<') === 0 && drupal_substr($next, drupal_strlen($next) - 1) === '>') { + $processed[$j] .= $piece; + $j++; + } + else { + $processed[$j] .= $piece; + } + } + return $processed; + } + + /** + * Merge copy and equivalent edits into intelligible chunks. + */ + function process_edits($edits) { + $processed = array(); + $current = array_shift($edits); + + // Make two passes -- first merge space delimiter copies back into their originals. + while ($chunk = array_shift($edits)) { + if ($chunk->type == 'copy' && $chunk->orig === array(' ')) { + $current->orig = array_merge((array) $current->orig, (array) $chunk->orig); + $current->closing = array_merge((array) $current->closing, (array) $chunk->closing); + } + else { + $processed[] = $current; + $current = $chunk; + } + } + $processed[] = $current; + + // Initial setup + $edits = $processed; + $processed = array(); + $current = array_shift($edits); + + // Second, merge equivalent chunks into each other. + while ($chunk = array_shift($edits)) { + if ($current->type == $chunk->type) { + $current->orig = array_merge((array) $current->orig, (array) $chunk->orig); + $current->closing = array_merge((array) $current->closing, (array) $chunk->closing); + } + else { + $processed[] = $current; + $current = $chunk; + } + } + $processed[] = $current; + + return $processed; + } +} diff --git a/profiles/wcm_base/modules/contrib/diff/LICENSE.txt b/profiles/wcm_base/modules/contrib/diff/LICENSE.txt new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/LICENSE.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/profiles/wcm_base/modules/contrib/diff/css/diff.boxes.css b/profiles/wcm_base/modules/contrib/diff/css/diff.boxes.css new file mode 100644 index 00000000..ee1b3116 --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/css/diff.boxes.css @@ -0,0 +1,124 @@ + +html.js .diff-js-hidden { display: none; } + +/* Reset as many core themes as possible */ +table.diff { + font-size: 0.923em; + margin: 0 0 10px; + border: 0 none; + width: 98%; + border-spacing: 5px; + table-layout: fixed ; + border-collapse: separate; +} +table.diff tr td:last-child { + border-right: inherit; +} +table.diff td, +table.diff th { + vertical-align: middle; + border: 0 none; + color: #000; + text-transform: none; + background: none; + border-spacing: 4px; + padding: 4px 8px; +} +table.diff tr, table.diff tr.even { + background: none; +} +table.diff tr th, table.diff tr th a, table.diff tr th a:hover { + color: inherit; + font-weight: bold; +} +table.diff tr.even, +table.diff tr.odd { + border-width: 0; + border-style: none; + background: transparent; +} +table.diff th a { display: inline; } + +/* Main theming */ +table.diff, td.diff-number { + background-color: white +} + +table.diff td.diff-lineno { + font-weight: bold +} + +table.diff td.diff-addedline, table.diff td.diff-deletedline, table.diff td.diff-context { + font-size: 88%; + vertical-align: top; + white-space: -moz-pre-wrap; + white-space: pre-wrap +} + +table.diff td.diff-addedline, table.diff td.diff-deletedline { + border-style: solid; + border-width: 1px 1px 1px 4px; + border-radius: 0.33em +} + +table.diff td.diff-context { + background: #f3f3f3; + color: #333333; + border-style: solid; + border-width: 1px 1px 1px 4px; + border-color: #e6e6e6; + border-radius: 0.33em; +} +table.diff td.diff-addedline { + border-color: #a3d3ff; + background: #ffffff; + border: 1px 1px 1px 3px; +} + +table.diff td.diff-deletedline { + border-color: #ffe49c +} + +.diffchange { + font-weight: bold; + text-decoration: none +} + +table.diff td.diff-addedline .diffchange, table.diff td.diff-deletedline .diffchange { + border-radius: 0.33em; + padding: 0.25em 0 +} + +table.diff td.diff-addedline .diffchange { + background: #d8ecff +} + +table.diff td.diff-deletedline .diffchange { + background: #feeec8 +} + +table.diff table.diff td { + padding: 0.33em 0.66em +} + +table.diff td.diff-marker { + width: 2%; + text-align: right; + font-weight: bold; + font-size: 1.25em +} + +table.diff col.diff-content { + width: 48% +} + +table.diff table.diff td div { + word-wrap: break-word; + overflow: auto +} +td.diff-prevlink { + text-align: left; +} +td.diff-nextlink { + text-align: right; +} diff --git a/profiles/wcm_base/modules/contrib/diff/css/diff.default.css b/profiles/wcm_base/modules/contrib/diff/css/diff.default.css new file mode 100644 index 00000000..a7ab7ffd --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/css/diff.default.css @@ -0,0 +1,86 @@ + +html.js .diff-js-hidden { display: none; } + +/** + * Inline diff metadata + */ +.diff-inline-metadata { + padding:4px; + border:1px solid #ddd; + background:#fff; + margin:0px 0px 10px; +} + +.diff-inline-legend { font-size:11px; } + +.diff-inline-legend span, +.diff-inline-legend label { margin-right:5px; } + +/** + * Inline diff markup + */ +span.diff-deleted { color:#ccc; } +span.diff-deleted img { border: solid 2px #ccc; } +span.diff-changed { background:#ffb; } +span.diff-changed img { border:solid 2px #ffb; } +span.diff-added { background:#cfc; } +span.diff-added img { border: solid 2px #cfc; } + +/** + * Traditional split diff theming + */ +table.diff { + border-spacing: 4px; + margin-bottom: 20px; + table-layout: fixed; + width: 100%; +} +table.diff tr.even, table.diff tr.odd { + background-color: inherit; + border: none; +} +td.diff-prevlink { + text-align: left; +} +td.diff-nextlink { + text-align: right; +} +td.diff-section-title, div.diff-section-title { + background-color: #f0f0ff; + font-size: 0.83em; + font-weight: bold; + padding: 0.1em 1em; +} +td.diff-context { + background-color: #fafafa; +} +td.diff-deletedline { + background-color: #ffa; + width: 50%; +} +td.diff-addedline { + background-color: #afa; + width: 50%; +} +span.diffchange { + color: #f00; + font-weight: bold; +} + +table.diff col.diff-marker { + width: 1.4em; +} +table.diff col.diff-content { + width: 50%; +} +table.diff th { + padding-right: inherit; +} +table.diff td div { + overflow: auto; + padding: 0.1ex 0.5em; + word-wrap: break-word; +} +table.diff td { + padding: 0.1ex 0.4em; +} diff --git a/profiles/wcm_base/modules/contrib/diff/diff.admin.inc b/profiles/wcm_base/modules/contrib/diff/diff.admin.inc new file mode 100644 index 00000000..a9df19ed --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/diff.admin.inc @@ -0,0 +1,158 @@ +<?php + +/** + * @file + * Administration page callbacks and forms. + */ + +/** + * General configuration form for controlling the diff behaviour. + */ +function diff_admin_settings($form, $form_state) { + $form['diff_theme'] = array( + '#type' => 'select', + '#title' => t('CSS options'), + '#default_value' => variable_get('diff_theme', 'default'), + '#options' => array( + 'default' => t('Classic'), + 'boxes' => t('Boxes'), + ), + '#empty_option' => t('- None -'), + '#description' => t('Alter the CSS used when displaying diff results.'), + ); + $form['diff_default_state_node'] = array( + '#type' => 'select', + '#title' => t('Diff default state'), + '#default_value' => variable_get('diff_default_state_node', 'raw'), + '#options' => array( + 'raw' => t('HTML view'), + 'raw_plain' => t('Plain view'), + ), + '#empty_option' => t('- None -'), + '#description' => t('Default display to show when viewing a diff, html tags in diffed result or as plain text.'), + ); + $form['diff_radio_behavior'] = array( + '#type' => 'select', + '#title' => t('Diff radio behavior'), + '#default_value' => variable_get('diff_radio_behavior', 'simple'), + '#options' => array( + 'simple' => t('Simple exclusion'), + 'linear' => t('Linear restrictions'), + ), + '#empty_option' => t('- None -'), + '#description' => t('<em>Simple exclusion</em> means that users will not be able to select the same revision, <em>Linear restrictions</em> means that users can only select older or newer revisions of the current selections.'), + ); + + $options = drupal_map_assoc(array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); + $form['diff_context_lines_leading'] = array( + '#type' => 'select', + '#title' => t('Leading context lines'), + '#description' => t('This governs the number of unchanged leading context "lines" to preserve.'), + '#default_value' => variable_get('diff_context_lines_leading', 2), + '#options' => $options, + ); + $form['diff_context_lines_trailing'] = array( + '#type' => 'select', + '#title' => t('Trailing context lines'), + '#description' => t('This governs the number of unchanged trailing context "lines" to preserve.'), + '#default_value' => variable_get('diff_context_lines_trailing', 2), + '#options' => $options, + ); + + return system_settings_form($form); +} + +/** + * Global entity settings. + */ +function diff_admin_global_entity_settings($form, $form_state, $entity_type) { + $entity_info = entity_get_info($entity_type); + drupal_set_title(t('Diff settings for %entity_label entities', array('%entity_label' => $entity_info['label'])), PASS_THROUGH); + $form['diff_show_header_' . $entity_type] = array( + '#type' => 'checkbox', + '#title' => t('Show entity label header'), + '#default_value' => variable_get('diff_show_header_' . $entity_type, 1), + ); + $form['diff_admin_path_' . $entity_type] = array( + '#type' => 'checkbox', + '#title' => t('Treat diff pages as administrative'), + '#description' => t('Diff pages are treated as administrative pages by default, although it is up to each module to enforce this and to implement this optional setting.'), + '#default_value' => variable_get('diff_admin_path_' . $entity_type, 1), + ); + return system_settings_form($form); +} + +/** + * Menu callback - provides an overview of Diff support and global settings. + */ +function diff_admin_field_overview() { + $build['info'] = array( + '#markup' => '<p>' . t('This table provides a summary of the field type support found on the system. It is recommended that you use global settings whenever possible to configure field comparison settings.') . '</p>', + ); + + $header = array(t('Type'), t('Module'), t('Operations')); + $rows = array(); + + // Skip field types which have no widget types. + $field_types = field_info_field_types(); + $widgets = array(); + foreach (field_info_widget_types() as $name => $widget_type) { + foreach ($widget_type['field types'] as $widget_field_type) { + if (isset($field_types[$widget_field_type])) { + $widgets[$widget_field_type][$name] = $widget_type['label']; + } + } + } + + foreach ($field_types as $field_name => $field_type) { + if (!empty($widgets[$field_name])) { + $row = array(); + $row[] = t('@field_label (%field_type)', array( + '@field_label' => $field_type['label'], + '%field_type' => $field_name, + )); + $row[] = $field_type['module']; + $row[] = l(t('Global settings'), 'admin/config/content/diff/fields/' . $field_name); + $rows[] = $row; + } + } + + $build['category_table'] = array( + '#theme' => 'table', + '#header' => $header, + '#rows' => $rows, + '#empty' => t('The system has no configurable fields.'), + ); + return $build; +} + +/** + * Menu form callback for the field settings. + */ +function diff_admin_global_field_settings($form, $form_state, $type) { + module_load_include('diff.inc', 'diff'); + + $field_types = field_info_field_types(); + if (!isset($field_types[$type])) { + drupal_set_message(t('Invalid field type.'), 'error'); + drupal_goto('admin/config/content/diff/fields'); + } + $field_type = $field_types[$type]; + + // Set the title to give more context to this page. + drupal_set_title(t('Global settings for %label fields', array( + '%label' => $field_type['label'], + )), PASS_THROUGH); + + $variable_name = "diff_{$field_type['module']}_field_{$type}_default_options"; + $settings = variable_get($variable_name, array()); + $settings = _diff_field_default_settings($field_type['module'], $type, $settings); + $func = $field_type['module'] . '_field_diff_options_form'; + if (function_exists($func) && ($options_form = $func($type, $settings))) { + $form[$variable_name] = $options_form; + } + $form[$variable_name]['#tree'] = TRUE; + + diff_global_settings_form($form[$variable_name], $form_state, $type, $settings); + return system_settings_form($form); +} diff --git a/profiles/wcm_base/modules/contrib/diff/diff.api.php b/profiles/wcm_base/modules/contrib/diff/diff.api.php new file mode 100644 index 00000000..507293a1 --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/diff.api.php @@ -0,0 +1,181 @@ +<?php + +/** + * @file + * Hooks provided by the diff module. + */ + +/** + * @addtogroup hooks + * @{ + */ + +/** + * Allow modules to provide a comparison about entities. + * + * @param object $old_entity + * The older entity revision. + * @param object $new_entity + * The newer entity revision. + * @param array $context + * An associative array containing: + * - entity_type: The entity type; e.g., 'node' or 'user'. + * - view_mode: The view mode to use. Defaults to FALSE. + * + * @return array + * An associative array of values keyed by the entity property. + * + * @todo + * Investiagate options and document these. + */ +function hook_entity_diff($old_entity, $new_entity, $context) { + if ($context['entity_type'] == 'node') { + $type = node_type_get_type($new_entity); + $result['title'] = array( + '#name' => $type->title_label, + '#old' => array($old_entity->title), + '#new' => array($new_entity->title), + '#weight' => -5, + '#settings' => array( + 'show_header' => FALSE, + ), + ); + } +} + +/** + * Allow modules to alter a comparison about entities. + * + * @param array $entity_diffs + * An array of entity differences. + * @param array $context + * An associative array containing: + * - entity_type: The entity type; e.g., 'node' or 'user'. + * - old_entity: The older entity. + * - new_entity: The newer entity. + * - view_mode: The view mode to use. Defaults to FALSE. + * + * @see hook_entity_diff() + */ +function hook_entity_diff_alter($entity_diffs, $context) { +} + +/** + * Callback to the module that defined the field to prepare items comparison. + * + * This allows the module to alter all items prior to rendering the comparative + * values. It is mainly used to bulk load entities to reduce overheads + * associated with loading entities individually. + * + * @param array $old_items + * An array of field items from the older revision. + * @param array $new_items + * An array of field items from the newer revision. + * @param array $context + * An associative array containing: + * - entity_type: The entity type; e.g., 'node' or 'user'. + * - bundle: The bundle name. + * - field: The field that the items belong to. + * - instance: The instance that the items belong to. + * - language: The language associated with $items. + * - old_entity: The older entity. + * - new_entity: The newer entity. + * + * @see MODULE_field_diff_view() + */ +function MODULE_field_diff_view_prepare(&$old_items, &$new_items, $context) { + $fids = array(); + foreach (array_merge_recursive($old_items, $new_items) as $info) { + $fids[$info['fid']] = $info['fid']; + } + // A single load is much faster than individual loads. + $files = file_load_multiple($fids); + + // For ease of processing, store a reference of the entity on the item array. + foreach ($old_items as $delta => $info) { + $old_items[$delta]['file'] = isset($files[$info['fid']]) ? $files[$info['fid']] : NULL; + } + foreach ($new_items as $delta => $info) { + $new_items[$delta]['file'] = isset($files[$info['fid']]) ? $files[$info['fid']] : NULL; + } +} + +/** + * Callback to the module that defined the field to generate items comparisons. + * + * @param array $items + * An array of field items from the entity. + * @param array $context + * An associative array containing: + * - entity: The entity being compared. + * - entity_type: The entity type; e.g., 'node' or 'user'. + * - bundle: The bundle name. + * - field: The field that the items belong to. + * - instance: The instance that the items belong to. + * - language: The language associated with $items. + * - old_entity: The older entity. + * - new_entity: The newer entity. + * + * @see MODULE_field_diff_view_prepare() + */ +function MODULE_field_diff_view($items, $context) { + $diff_items = array(); + foreach ($items as $delta => $item) { + if (isset($item['file'])) { + $diff_items[$delta] = $item['file']->filename . ' [fid: ' . $item['fid'] . ']'; + } + } + + return $diff_items; +} + +/** + * Allow other modules to interact with MODULE_field_diff_view_prepare(). + * + * @param array $old_items + * An array of field items from the older revision. + * @param array $new_items + * An array of field items from the newer revision. + * @param array $context + * An associative array containing: + * - entity_type: The entity type; e.g., 'node' or 'user'. + * - bundle: The bundle name. + * - field: The field that the items belong to. + * - instance: The instance that the items belong to. + * - language: The language associated with $items. + * - old_entity: The older entity. + * - new_entity: The newer entity. + * + * @see MODULE_field_diff_view_prepare() + */ +function hook_field_diff_view_prepare_alter($old_items, $new_items, $context) { + +} + +/** + * Allow other modules to interact with MODULE_field_diff_view(). + * + * @param array $values + * An array of field items from the entity ready for comparison. + * @param array $items + * An array of field items from the entity. + * @param array $context + * An associative array containing: + * - entity: The entity being compared. + * - entity_type: The entity type; e.g., 'node' or 'user'. + * - bundle: The bundle name. + * - field: The field that the items belong to. + * - instance: The instance that the items belong to. + * - language: The language associated with $items. + * - old_entity: The older entity. + * - new_entity: The newer entity. + * + * @see MODULE_field_diff_view() + */ +function hook_field_diff_view_alter($values, $items, $context) { + +} + +/** + * @} End of "addtogroup hooks". + */ diff --git a/profiles/wcm_base/modules/contrib/diff/diff.css b/profiles/wcm_base/modules/contrib/diff/diff.css new file mode 100644 index 00000000..a09147c1 --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/diff.css @@ -0,0 +1,86 @@ + +html.js .diff-js-hidden { display:none; } + +/** + * Inline diff metadata + */ +.diff-inline-metadata { + padding:4px; + border:1px solid #ddd; + background:#fff; + margin:0px 0px 10px; + } + +.diff-inline-legend { font-size:11px; } + +.diff-inline-legend span, +.diff-inline-legend label { margin-right:5px; } + +/** + * Inline diff markup + */ +span.diff-deleted { color:#ccc; } +span.diff-deleted img { border: solid 2px #ccc; } +span.diff-changed { background:#ffb; } +span.diff-changed img { border:solid 2px #ffb; } +span.diff-added { background:#cfc; } +span.diff-added img { border: solid 2px #cfc; } + +/** + * Traditional split diff theming + */ +table.diff { + border-spacing: 4px; + margin-bottom: 20px; + table-layout: fixed; + width: 100%; +} +table.diff tr.even, table.diff tr.odd { + background-color: inherit; + border: none; +} +td.diff-prevlink { + text-align: left; +} +td.diff-nextlink { + text-align: right; +} +td.diff-section-title, div.diff-section-title { + background-color: #f0f0ff; + font-size: 0.83em; + font-weight: bold; + padding: 0.1em 1em; +} +td.diff-deletedline { + background-color: #ffa; + width: 50%; +} +td.diff-addedline { + background-color: #afa; + width: 50%; +} +td.diff-context { + background-color: #fafafa; +} +span.diffchange { + color: #f00; + font-weight: bold; +} + +table.diff col.diff-marker { + width: 1.4em; +} +table.diff col.diff-content { + width: 50%; +} +table.diff th { + padding-right: inherit; +} +table.diff td div { + overflow: auto; + padding: 0.1ex 0.5em; + word-wrap: break-word; +} +table.diff td { + padding: 0.1ex 0.4em; +} diff --git a/profiles/wcm_base/modules/contrib/diff/diff.diff.inc b/profiles/wcm_base/modules/contrib/diff/diff.diff.inc new file mode 100644 index 00000000..63c01b44 --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/diff.diff.inc @@ -0,0 +1,384 @@ +<?php + +/** + * @file + * Includes the hooks defined by diff_hook_info(). + */ + +/** + * Implements hook_entity_diff(). + * + * Helper function to invoke the depreciated hook_diff() for node entities. + * + * This manually invokes hook_diff() to avoid a function name clash with the + * PHP 5 (>= 5.3.0) date_diff() function or the Dates modules implementation. + * + * @param object $old_entity + * The older node revision. + * @param object $new_entity + * The newer node revision. + * @param array $context + * An associative array containing: + * - entity_type: The entity type; e.g., 'node' or 'user'. + * - old_entity: The older entity. + * - new_entity: The newer entity. + * - view_mode: The view mode to use. Defaults to FALSE. + */ +function diff_entity_diff($old_entity, $new_entity, $context) { + $return = array(); + + $entity_type = $context['entity_type']; + $info = entity_get_info($entity_type); + if (!empty($info['fieldable'])) { + $return = diff_entity_fields_diff($old_entity, $new_entity, $context); + } + + return $return; +} + +/** + * Internal callback to handle fieldable entities. + * + * Field comparison is handled for core modules, but is expandable to any other + * fields if the module defines MODULE_field_diff_view(). + * + * @param object $old_entity + * The older entity entity revision. + * @param object $new_entity + * The newer entity entity revision. + * @param array $context + * An associative array containing: + * - entity_type: The entity type; e.g., 'node' or 'user'. + * - old_entity: The older entity. + * - new_entity: The newer entity. + * - view_mode: The view mode to use. Defaults to FALSE. + * + * @return array + * An associative array of values keyed by the field name and delta value. + */ +function diff_entity_fields_diff($old_entity, $new_entity, $context) { + $result = array(); + + $entity_type = $context['entity_type']; + $view_mode = $context['view_mode']; + + $field_context = $context; + + $actual_mode = FALSE; + list(,, $bundle_name) = entity_extract_ids($entity_type, $new_entity); + $instances = field_info_instances($entity_type, $bundle_name); + + // Some fields piggy back the display settings, so we need to fake these by + // ensuring that the field mode is always set. + if (empty($view_mode)) { + $actual_mode = 'diff_standard'; + $field_context['custom_settings'] = FALSE; + } + $view_mode_settings = field_view_mode_settings($entity_type, $bundle_name); + $actual_mode = (!empty($view_mode_settings[$view_mode]['custom_settings'])) ? $view_mode : 'default'; + if (!isset($field_context['custom_settings'])) { + $field_context['custom_settings'] = $actual_mode && $actual_mode == $view_mode; + } + + $field_context['old_entity'] = $old_entity; + $field_context['new_entity'] = $new_entity; + $field_context['bundle_name'] = $bundle_name; + + foreach ($instances as $instance) { + // Any view mode is supported in relation to hiding fields, but only if + // selected (todo see if this is a valid option). + if ($actual_mode && $instance['display'][$actual_mode]['type'] == 'hidden') { + continue; + } + $field_name = $instance['field_name']; + $field = field_info_field($field_name); + $field_context['field'] = $field; + $field_context['instance'] = $instance; + $field_context['display'] = $instance['display'][$actual_mode]; + + // We provide a loose check on the field access. + if (field_access('view', $field, $entity_type) || field_access('edit', $field, $entity_type)) { + $langcode = field_language($entity_type, $new_entity, $field_name); + + $field_context['language'] = $langcode; + $field_context['field'] = $field; + $field_context['instance'] = $instance; + + $old_items = array(); + if (!empty($old_entity->{$field_name}[$langcode])) { + $old_items = $old_entity->{$field_name}[$langcode]; + } + + $new_items = array(); + if (!empty($new_entity->{$field_name}[$langcode])) { + $new_items = $new_entity->{$field_name}[$langcode]; + } + + // Load files containing the field callbacks. + _diff_autoload($field); + + $field_context['settings'] = diff_get_field_settings($field_context); + + // Reference fields can optionally prepare objects in bulk to reduce + // overheads related to multiple database calls. If a field considers + // that the delta values is meaningless, they can order and rearrange + // to provide cleaner results. + $func = $field['module'] . '_field_diff_view_prepare'; + if (function_exists($func)) { + $func($old_items, $new_items, $field_context); + } + // Allow other modules to act safely on behalf of the core field module. + drupal_alter('field_diff_view_prepare', $old_items, $new_items, $field_context); + + // These functions compiles the items into comparable arrays of strings. + $func = $field['module'] . '_field_diff_view'; + if (!function_exists($func)) { + $func = 'diff_field_diff_view'; + } + + // These callbacks should be independent of revision. + $old_context = $field_context; + $old_context['entity'] = $old_entity; + $old_values = $func($old_items, $old_context); + $new_context = $field_context; + $new_context['entity'] = $new_entity; + $new_values = $func($new_items, $new_context); + + // Allow other modules to act safely on behalf of the core field module. + drupal_alter('field_diff_view', $old_values, $old_items, $old_context); + drupal_alter('field_diff_view', $new_values, $new_items, $new_context); + + $max = max(array(count($old_values), count($new_values))); + if ($max) { + $result[$field_name] = array( + '#name' => $instance['label'], + '#old' => array(), + '#new' => array(), + '#settings' => $field_context['settings'], + ); + for ($delta = 0; $delta < $max; $delta++) { + if (isset($old_values[$delta])) { + $result[$field_name]['#old'][] = is_array($old_values[$delta]) ? implode("\n", $old_values[$delta]) : $old_values[$delta]; + } + if (isset($new_values[$delta])) { + $result[$field_name]['#new'][] = is_array($new_values[$delta]) ? implode("\n", $new_values[$delta]) : $new_values[$delta]; + } + } + $result[$field_name]['#old'] = implode("\n", $result[$field_name]['#old']); + $result[$field_name]['#new'] = implode("\n", $result[$field_name]['#new']); + + if ($actual_mode) { + $result[$field_name]['#weight'] = $instance['display'][$actual_mode]['weight']; + } + + } + } + } + return $result; +} + +/** + * A generic handler for parsing field values. + * + * This callback can only handle the most basic of fields that populates the + * safe_value during field load or use the value column for data storage. + * + * @param array $items + * An array of field items. + * @param array $context + * An associative array containing: + * - entity: The entity that the items belong to. + * - entity_type: The entity type; e.g., 'node' or 'user'. + * - bundle: The bundle name. + * - field: The field that the items belong to. + * - instance: The instance that the items belong to. + * - language: The language associated with $items. + * - old_entity: The older entity. + * - new_entity: The newer entity. + * + * @return array + * An array of strings representing the value, keyed by delta index. + */ +function diff_field_diff_view($items, $context) { + $diff_items = array(); + $entity = clone $context['entity']; + $langcode = field_language($context['entity_type'], $entity, $context['field']['field_name']); + $view_mode = empty($context['view_mode']) ? 'diff_standard' : $context['view_mode']; + $element = field_view_field($context['entity_type'], $entity, $context['field']['field_name'], $view_mode, $langcode); + + foreach (element_children($element) as $delta) { + $diff_items[$delta] = drupal_render($element[$delta]); + } + return $diff_items; +} + +/** + * Helper function to get the settings for a given field or formatter. + * + * @param array $context + * This will get the settings for a field. + * - field (required): The field that the items belong to. + * - entity: The entity that we are looking up. + * - instance: The instance that the items belong to. + * - view_mode: The view mode to use. Defaults to FALSE. + * + * @return array + * The settings for this field type. + */ +function diff_get_field_settings($field_context) { + $field = $field_context['field']; + + // Update saved settings from the global settings for this field type. + $settings = variable_get("diff_{$field['module']}_field_{$field['type']}_default_options", array()); + + $settings = _diff_field_default_settings($field['module'], $field['type'], $settings); + + // Allow modules to alter the field settings based on the current context. + drupal_alter('diff_field_settings', $settings, $field_context); + + return $settings; +} + +/** + * Helper function to initiate any global form elements. + */ +function diff_global_settings_form(&$subform, $form_state, $type, $settings) { + $subform['show_header'] = array( + '#type' => 'checkbox', + '#title' => t('Show field title'), + '#default_value' => $settings['show_header'], + '#weight' => -5, + ); + $subform['markdown'] = array( + '#type' => 'select', + '#title' => t('Markdown callback'), + '#default_value' => $settings['markdown'], + '#options' => array( + 'drupal_html_to_text' => t('Drupal HTML to Text'), + 'filter_xss' => t('Filter XSS (some tags)'), + 'diff_filter_xss' => t('Filter XSS (all tags)'), + ), + '#description' => t('These provide ways to clean markup tags to make comparisons easier to read.'), + '#empty_option' => t('- Do not process -'), + ); + $subform['line_counter'] = array( + '#type' => 'radios', + '#title' => t('Line counter'), + '#default_value' => $settings['line_counter'], + '#description' => t('This outputs the (approximate) line numbers as a heading before every change.'), + '#options' => array( + '' => t('None. Counter ignore and not incremented.'), + 'hidden' => t('Count lines but do not show line headers.'), + 'line' => t('Count and show lines, restarting counter at 0.'), + 'line_continuous' => t('Count and show lines, incrementing counter from last item.'), + ), + ); + + /* +This would be cool, but to do anything else than inline with the text appears +to be very hard, requiring a refactoring of both the modules API but also the +DiffFormatter and Diff classes. Diff 8.x-4.x maybe. + + $subform['show_delta'] = array( + '#type' => 'checkbox', + '#title' => t('Show delta values'), + '#default_value' => $settings['show_delta'], + ); + $subform['delta_format'] = array( + '#type' => 'radios', + '#title' => t('Delta insertion method'), + '#default_value' => $settings['delta_format'], + '#options' => array( + 'inline' => t('Prefix to item'), + 'row' => t('Individual row'), + ), + '#states' => array( + 'invisible' => array( + "input[id$='show-delta']" => array('checked' => FALSE), + ), + ), + ); + */ +} + +/** + * Helper function to populate the settings array. + */ +function _diff_field_default_settings($module, $field_type, $settings = array()) { + // Load files containing the field callbacks. + _diff_autoload($module); + + // Populate any missing values from CALLBACK_field_diff_default_options(). + $func = $module . '_field_diff_default_options'; + if (function_exists($func)) { + $settings += $func($field_type); + } + + // Check for Diff support. If it doesn't exist, the default markdown should + // escape the field display, otherwise a raw format should be used. + $func = $module . '_field_diff_view'; + + // Global settings. + $settings += array( + 'markdown' => function_exists($func) ? '' : 'drupal_html_to_text', + 'line_counter' => '', + 'show_header' => 1, + // Can we? This seems too hard to track in the DiffFormatter as all we + // have is a string or an array of strings. + //'show_delta' => 0, + //'delta_format' => 'row', + ); + return $settings; +} + +/** + * Private helper function to load field includes. + * + * @param array|string $field_or_module + * The field definition array or the module that implements the field. + */ +function _diff_autoload($field_or_module) { + $includes = &drupal_static(__FUNCTION__, FALSE); + if (!$includes) { + $includes = array( + 'file' => module_exists('file'), + 'image' => module_exists('image'), + 'list' => module_exists('list'), + 'taxonomy' => module_exists('taxonomy'), + 'text' => module_exists('text'), + 'number' => module_exists('number'), + ); + } + + $module = is_string($field_or_module) ? $field_or_module : $field_or_module['module']; + + // Since field hooks are not real hooks, we manually load the field modules + // MODULE.diff.inc. We handle the five core field defining modules. + if (!isset($includes[$module])) { + module_load_include('diff.inc', $module); + $includes[$module] = 0; + } + elseif (!empty($includes[$module])) { + module_load_include('inc', 'diff', 'includes/' . $module); + $includes[$module] = 0; + } +} + +/** + * Helper function to parse out the state in the diff results. + */ +function diff_extract_state($diff, $state = 'raw') { + $states = array( + 0 => NULL, + 1 => NULL, + ); + if (isset($diff['#states'][$state])) { + if (isset($diff['#states'][$state]['#old'])) { + $states[0] = $diff['#states'][$state]['#old']; + } + if (isset($diff['#states'][$state]['#new'])) { + $states[1] = $diff['#states'][$state]['#new']; + } + } + return $states; +} diff --git a/profiles/wcm_base/modules/contrib/diff/diff.info b/profiles/wcm_base/modules/contrib/diff/diff.info new file mode 100644 index 00000000..5ae077e8 --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/diff.info @@ -0,0 +1,12 @@ +name = Diff +description = Show differences between content revisions. +core = 7.x + +files[] = DiffEngine.php + +; Information added by drupal.org packaging script on 2012-11-13 +version = "7.x-3.2" +core = "7.x" +project = "diff" +datestamp = "1352784357" + diff --git a/profiles/wcm_base/modules/contrib/diff/diff.install b/profiles/wcm_base/modules/contrib/diff/diff.install new file mode 100644 index 00000000..16f1d27c --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/diff.install @@ -0,0 +1,124 @@ +<?php + +/** + * @file + * Provides uninstallation functions. + */ + +/** + * Implements hook_uninstall(). + */ +function diff_uninstall() { + // Bulk delete entity based variables. + $prefixes = array( + 'diff_enable_revisions_page_', + 'diff_show_', + 'diff_view_mode_', + 'diff_admin_path_', + 'diff_default_state_', + ); + foreach ($prefixes as $prefix) { + db_delete('variable') + ->condition('name', db_like($prefix) . '%', 'LIKE') + ->execute(); + } + + // Delete global variables. + variable_del('diff_context_lines_trailing'); + variable_del('diff_context_lines_leading'); + variable_del('diff_theme'); + variable_del('diff_radio_behavior', ''); + + foreach (field_info_fields() as $field) { + variable_del("diff_{$field['module']}_field_{$field['type']}_default_options"); + } +} + +/** + * Updates the existing system variables to target the entity type and bundle. + */ +function diff_update_7300() { + $node_types = array_keys(node_type_get_types()); + foreach ($node_types as $bundle) { + $type_variables = array( + 'show_preview_changes', + 'enable_revisions_page', + 'show_diff_inline', + ); + foreach ($type_variables as $prefix) { + $setting = variable_get($prefix . '_' . $bundle, NULL); + if (isset($setting)) { + variable_del($prefix . '_' . $bundle); + variable_set('diff_' . $prefix . '_node_' . $bundle, $setting); + } + } + } +} + +/** + * Removed diff_update_7301(). + */ + +/** + * Removed diff_update_7302(). + */ + +/** + * Renames some internal settings names. + */ +function diff_update_7303() { + // Get current values + $radio = variable_get('diff_script_revisioning', 'simple'); + $leading = variable_get('diff_leading_context_lines', 2); + $trailing = variable_get('diff_trailing_context_lines', 2); + // Create new variable names + variable_set('diff_radio_behavior', $radio); + variable_set('diff_context_lines_leading', $leading); + variable_set('diff_context_lines_trailing', $trailing); + // Delete old variables + variable_del('diff_script_revisioning'); + variable_del('diff_leading_context_lines'); + variable_del('diff_trailing_context_lines'); +} + +/** + * Removes unused variable settings and merges inline diff block settings. + */ +function diff_update_7304() { + // This is now always applied to text fields. + variable_del('diff_normalise_text'); + + // Merge the content type settings for the inline diff block into a single variable. + // diff_update_7300() - show_diff_inline_TYPE to diff_show_diff_inline_node_TYPE + $node_types = array_keys(node_type_get_types()); + $enabled_types = array(); + foreach ($node_types as $node_type) { + if (variable_get('diff_show_diff_inline_node_' . $node_type, FALSE)) { + $enabled_types[$node_type] = $node_type; + } + variable_del('diff_show_diff_inline_node_' . $node_type); + } + variable_set('diff_show_diff_inline_node_bundles', $enabled_types); + + // Warn users that these settings are altered. + drupal_set_message(t('Diff <em>Inline differences</em> content type settings are now located within the <em>Inline differences</em> block settings.')); +} + +/** + * Updates to normalize the new view mode settings. + */ +function diff_update_7305() { + // Rebuild the menus. + variable_set('menu_rebuild_needed', TRUE); + + // Removed the enforced entity view mode. + db_delete('variable') + ->condition('name', db_like('diff_view_mode_standard_node_') . '%', 'LIKE') + ->execute(); + + // Removes the configurable view mode for the inline diff block, as this + // is fairly meaningless and confusing to users. + db_delete('variable') + ->condition('name', db_like('diff_view_mode_inline_') . '%', 'LIKE') + ->execute(); +} diff --git a/profiles/wcm_base/modules/contrib/diff/diff.module b/profiles/wcm_base/modules/contrib/diff/diff.module new file mode 100644 index 00000000..f58e1d72 --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/diff.module @@ -0,0 +1,623 @@ +<?php + +/** + * @file + * Provides functionality to show a diff between two node revisions. + */ + +/** + * Number of items on one page of the revision list. + */ +define('REVISION_LIST_SIZE', 50); + +/** + * Exposed sorting options. + * + * No sorting means sorting by delta value for fields. + */ +define('DIFF_SORT_NONE', '0'); + +/** + * Exposed sorting options. + * + * This normally sorts by the rendered comparison. + */ +define('DIFF_SORT_VALUE', '1'); + +/** + * Exposed sorting options. + * + * It is up to the field / entity to decide how to handle the sort. + */ +define('DIFF_SORT_CUSTOM', '-1'); + +/** + * Implements hook_help(). + */ +function diff_help($path, $arg) { + switch ($path) { + case 'admin/help#diff': + $output = '<p>' . t('The Diff module replaces the normal <em>Revisions</em> node tab. Diff enhances the listing of revisions with an option to view the differences between any two content revisions. Access to this feature is controlled with the <em>View revisions</em> permission. The feature can be disabled for an entire content type on the content type configuration page. Diff also provides an optional <em>View changes</em> button while editing a node.') . '</p>'; + return $output; + case 'node/%/revisions/%/view': + // The translated strings should match node_help('node/%/revisions'). + return '<p>' . t('Revisions allow you to track differences between multiple versions of your content, and revert back to older versions.') . '</p>'; + case 'node/%/revisions/view/%/%': + return '<p>' . t('Comparing two revisions:') . '</p>'; + } +} + +/** + * The various states that are available. + */ +function diff_available_states($entity_type = NULL) { + $states = array( + 'raw' => t('Standard'), + 'raw_plain' => t('Marked down'), + ); + + return $states; +} + +/** + * Implements hook_menu(). + * + * @todo: Review this. + */ +function diff_menu() { + /* + * By using MENU_LOCAL_TASK (and 'tab_parent') we can get the various + * revision-views to show the View|Edit|Revision-tabs of the node on top, + * and have the Revisions-tab open. To avoid creating/showing any extra tabs + * or sub-tabs (tasks below top level) for the various paths (i.e. "Diff", + * "Show latest" and "Show a specific revision") that need a revision-id (vid) + * parameter, we make sure to set 'tab_parent' a bit odd. This solution may + * not be the prettiest one, but by avoiding having two _LOCAL_TASKs sharing + * a parent that can be accessed by its full path, it seems to work as + * desired. Breadcrumbs work decently, at least the node link is among the + * crumbs. For some reason any breadcrumbs "before/above" the node is only + * seen at 'node/%node/revisions/%/view'. + */ + + // Not used directly, but was created to get the other menu items to work. + $items['node/%node/revisions/list'] = array( + 'title' => 'List revisions', + 'page callback' => 'diff_diffs_overview', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'access callback' => 'diff_node_revision_access', + 'access arguments' => array(1), + 'file' => 'diff.pages.inc', + ); + $items['node/%node/revisions/view'] = array( + 'title' => 'Compare revisions', + 'page callback' => 'diff_diffs_show', + 'page arguments' => array(1, 4, 5, 6), + 'type' => MENU_LOCAL_TASK, + 'access callback' => 'diff_node_revision_access', + 'access arguments' => array(1), + 'tab_parent' => 'node/%/revisions/list', + 'file' => 'diff.pages.inc', + ); + + $items['node/%node/revisions/view/latest'] = array( + 'title' => 'Show latest difference', + 'page callback' => 'diff_latest', + 'page arguments' => array(1), + 'type' => MENU_LOCAL_TASK, + 'access callback' => 'diff_node_revision_access', + 'access arguments' => array(1), + 'tab_parent' => 'node/%/revisions/view', + 'file' => 'diff.pages.inc', + ); + + // Administrative settings. + $items['admin/config/content/diff'] = array( + 'title' => 'Diff', + 'description' => 'Diff settings.', + 'file' => 'diff.admin.inc', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('diff_admin_settings'), + 'access arguments' => array('administer site configuration'), + ); + $items['admin/config/content/diff/settings'] = array( + 'title' => 'Settings', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + ); + $items['admin/config/content/diff/fields'] = array( + 'title' => 'Fields', + 'description' => 'Field support and settings overview.', + 'file' => 'diff.admin.inc', + 'page callback' => 'diff_admin_field_overview', + 'access arguments' => array('administer site configuration'), + 'type' => MENU_LOCAL_TASK, + ); + $items['admin/config/content/diff/fields/%'] = array( + 'title' => 'Global field settings', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('diff_admin_global_field_settings', 5), + 'access arguments' => array('administer site configuration'), + 'type' => MENU_VISIBLE_IN_BREADCRUMB, + 'file' => 'diff.admin.inc', + ); + + $items['admin/config/content/diff/entities'] = array( + 'title' => 'Entities', + 'description' => 'Entity settings.', + 'file' => 'diff.admin.inc', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('diff_admin_global_entity_settings', 'node'), + 'access arguments' => array('administer site configuration'), + 'type' => MENU_LOCAL_TASK, + ); + + $items['admin/config/content/diff/entities/node'] = array( + 'title' => 'Node', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + ); + + return $items; +} + +/** + * Implements hook_menu_alter(). + */ +function diff_menu_alter(&$callbacks) { + // Overwrite the default 'Revisions' page. + $callbacks['node/%node/revisions']['page callback'] = 'diff_diffs_overview'; + $callbacks['node/%node/revisions']['module'] = 'diff'; + $callbacks['node/%node/revisions']['file'] = 'diff.pages.inc'; + + $callbacks['node/%node/revisions/%/view']['tab_parent'] = 'node/%/revisions/list'; + $callbacks['node/%node/revisions/%/revert']['tab_parent'] = 'node/%/revisions/%/view'; + $callbacks['node/%node/revisions/%/delete']['tab_parent'] = 'node/%/revisions/%/view'; + + $callbacks['node/%node/revisions']['access callback'] + = $callbacks['node/%node/revisions/%/view']['access callback'] + = $callbacks['node/%node/revisions/%/revert']['access callback'] + = $callbacks['node/%node/revisions/%/delete']['access callback'] = 'diff_node_revision_access'; +} + +/** + * Implements hook_admin_paths_alter(). + */ +function diff_admin_paths_alter(&$paths) { + // By default, treat all diff pages as administrative. + if (variable_get('diff_admin_path_node', 1)) { + $paths['node/*/revisions/view/*/*'] = TRUE; + } +} + +/** + * Access callback for the node revisions page. + */ +function diff_node_revision_access($node, $op = 'view') { + $may_revision_this_type = variable_get('diff_enable_revisions_page_node_' . $node->type, TRUE) || user_access('administer nodes'); + return $may_revision_this_type && _node_revision_access($node, $op); +} + +/** + * Implements hook_hook_info(). + */ +function diff_hook_info() { + $hooks['entity_diff'] = array( + 'group' => 'diff', + ); + $hooks['diff'] = array( + 'group' => 'diff', + ); + $hooks['field_diff_view_prepare_alter'] = array( + 'group' => 'diff', + ); + $hooks['field_diff_view_alter'] = array( + 'group' => 'diff', + ); + + return $hooks; +} + +/** + * Implements hook_entity_info_alter(). + * + * Although the module only provides an UI for comparing nodes, it has an + * extendable API for any entity, so we supply two view modes for all entities. + * - diff_standard: This view mode is used to tell the module how to compare + * individual fields. This is used on the revisions page. + */ +function diff_entity_info_alter(&$entity_info) { + foreach (array_keys($entity_info) as $entity_type) { + if (!empty($entity_info[$entity_type]['view modes'])) { + $entity_info[$entity_type]['view modes'] += array( + 'diff_standard' => array( + 'label' => t('Revision comparison'), + 'custom settings' => FALSE, + ), + ); + } + } +} + +/** + * Implements hook_block_info(). + */ +function diff_block_info() { + return array( + 'inline' => array( + 'info' => t('Inline differences'), + ), + ); +} + +/** + * Implements hook_block_configure(). + */ +function diff_block_configure($delta = '') { + $form = array(); + switch ($delta) { + case 'inline': + $form['bundles'] = array( + '#type' => 'checkboxes', + '#title' => t('Enabled content types'), + '#default_value' => variable_get('diff_show_diff_inline_node_bundles', array()), + '#options' => node_type_get_names(), + '#description' => t('Show this block only on pages that display content of the given type(s).'), + ); + break; + } + return $form; +} + +/** + * Implements hook_block_save(). + */ +function diff_block_save($delta = '', $edit = array()) { + switch ($delta) { + case 'inline': + variable_set('diff_show_diff_inline_node_bundles', $edit['bundles']); + break; + } +} + +/** + * Implements hook_block_view(). + */ +function diff_block_view($delta) { + if ($delta === 'inline' && user_access('view revisions') && ($node = menu_get_object()) && arg(2) !== 'edit') { + $enabled_types = variable_get('diff_show_diff_inline_node_bundles', array()); + if (!empty($enabled_types[$node->type])) { + $block = array(); + $revisions = node_revision_list($node); + if (count($revisions) > 1) { + $block['subject'] = t('Highlight changes'); + $block['content'] = drupal_get_form('diff_inline_form', $node, $revisions); + } + return $block; + } + } +} + +/** + * Implements hook_node_view_alter(). + */ +function diff_node_view_alter(&$build) { + $node = $build['#node']; + if (user_access('view revisions') && in_array($node->type, variable_get('diff_show_diff_inline_node_bundles', array()))) { + // Ugly but cheap way to check that we are viewing a node's revision page. + if (arg(2) === 'revisions' && arg(3) === $node->vid) { + module_load_include('inc', 'diff', 'diff.pages'); + $old_vid = _diff_get_previous_vid(node_revision_list($node), $node->vid); + $build = array('#markup' => diff_inline_show($node, $old_vid)); + } + $build['#prefix'] = isset($build['#prefix']) ? "<div id='diff-inline-{$node->nid}'>" . $build['#prefix'] : "<div id='diff-inline-{$node->nid}'>"; + $build['#suffix'] = isset($build['#suffix']) ? $build['#suffix'] . "</div>" : "</div>"; + } +} + +/** + * Implements hook_form_BASE_FORM_ID_alter(). + */ +function diff_form_node_form_alter(&$form, $form_state) { + // Add a 'View changes' button on the node edit form. + $node = $form['#node']; + if (variable_get('diff_show_preview_changes_node_' . $node->type, TRUE) && !empty($node->nid)) { + $form['actions']['preview_changes'] = array( + '#type' => 'submit', + '#value' => t('View changes'), + '#weight' => 12, + '#submit' => array('diff_node_form_build_preview_changes'), + ); + } +} + +/** + * Implements hook_form_BASE_FORM_ID_alter(). + */ +function diff_form_node_type_form_alter(&$form, $form_state) { + if (isset($form['type'])) { + $type = $form['#node_type']; + $form['diff'] = array( + '#title' => t('Compare revisions'), + '#type' => 'fieldset', + '#group' => 'additional_settings', + '#tree' => FALSE, + ); + $form['diff']['diff_show_preview_changes_node'] = array( + '#type' => 'checkbox', + '#title' => t('Show <em>View changes</em> button on node edit form'), + '#weight' => 10, + '#default_value' => variable_get('diff_show_preview_changes_node_' . $type->type, TRUE), + ); + $form['diff']['diff_enable_revisions_page_node'] = array( + '#type' => 'checkbox', + '#title' => t('Enable the <em>Revisions</em> page for this content type'), + '#weight' => 11, + '#default_value' => variable_get('diff_enable_revisions_page_node_' . $type->type, TRUE), + ); + $options = array(); + $info = entity_get_info('node'); + foreach ($info['view modes'] as $view_mode => $view_mode_info) { + $options[$view_mode] = $view_mode_info['label']; + } + $form['diff']['diff_view_mode_preview_node'] = array( + '#type' => 'select', + '#title' => t('Standard comparison preview'), + '#description' => t('Governs the <em>Current revision</em> view mode when doing standard comparisons.'), + '#options' => $options, + '#weight' => 13, + '#default_value' => variable_get('diff_view_mode_preview_node_' . $type->type, 'full'), + '#empty_value' => '', + '#empty_option' => t('- Do not display -'), + ); + } +} + +/** + * Implements hook_node_type_update(). + * + * This tracks the diff settings in case the node content type is renamed. + */ +function diff_node_type_update($info) { + if (!empty($info->old_type) && $info->old_type != $info->type) { + $type_variables = array( + 'diff_show_preview_changes_node', + 'diff_enable_revisions_page_node', + 'diff_view_mode_preview_node', + ); + foreach ($type_variables as $prefix) { + $setting = variable_get($prefix . '_' . $info->old_type, NULL); + if (isset($setting)) { + variable_del($prefix . '_' . $info->old_type); + variable_set($prefix . '_' . $info->type, $setting); + } + } + + // Block settings are combined in a single variable. + $inline_block_types = variable_get('diff_show_diff_inline_node_bundles', array()); + if (isset($inline_block_types[$info->old_type])) { + if (!empty($inline_block_types[$info->old_type])) { + $inline_block_types[$info->type] = $info->type; + } + unset($inline_block_types[$info->old_type]); + variable_set('diff_show_diff_inline_node_bundles', $inline_block_types); + } + } +} + +/** + * Implements hook_node_type_delete(). + */ +function diff_node_type_delete($info) { + variable_del('diff_show_preview_changes_node_' . $info->type); + variable_del('diff_enable_revisions_page_node_' . $info->type); + variable_del('diff_view_mode_preview_node_' . $info->type); +} + +/** + * Submit handler for the 'View changes' action. + * + * @see node_form_build_preview() + */ +function diff_node_form_build_preview_changes($form, &$form_state) { + module_load_include('inc', 'diff', 'diff.pages'); + $old_node = clone node_load($form_state['values']['nid']); + $node = node_form_submit_build_node($form, $form_state); + + // Create diff of old node and edited node. + $rows = _diff_body_rows($old_node, $node); + + $header = _diff_default_header(t('Original'), t('Changes')); + $changes = theme('table__diff__preview', array( + 'header' => $header, + 'rows' => $rows, + 'attributes' => array('class' => 'diff'), + 'colgroups' => _diff_default_cols(), + 'sticky' => FALSE, + )); + + // Prepend diff to edit form. + $form_state['node_preview'] = $changes; + $form_state['rebuild'] = TRUE; +} + +/** + * Implements hook_theme(). + */ +function diff_theme() { + return array( + 'diff_node_revisions' => array( + 'render element' => 'form', + 'file' => 'diff.theme.inc', + ), + 'diff_header_line' => array( + 'arguments' => array('lineno' => NULL), + 'file' => 'diff.theme.inc', + ), + 'diff_content_line' => array( + 'arguments' => array('line' => NULL), + 'file' => 'diff.theme.inc', + ), + 'diff_empty_line' => array( + 'arguments' => array('line' => NULL), + 'file' => 'diff.theme.inc', + ), + 'diff_inline_form' => array( + 'render element' => 'form', + 'file' => 'diff.theme.inc', + ), + 'diff_inline_metadata' => array( + 'arguments' => array('node' => NULL), + 'file' => 'diff.theme.inc', + ), + 'diff_inline_chunk' => array( + 'arguments' => array('text' => '', 'type' => NULL), + 'file' => 'diff.theme.inc', + ), + ); +} + +/** + * Render the table rows for theme('table'). + * + * @param string $a + * The source string to compare from. + * @param string $b + * The target string to compare to. + * @param boolean $show_header + * Display diff context headers. For example, "Line x". + * @param array $line_stats + * This structure tracks line numbers across multiple calls to DiffFormatter. + * + * @return array + * Array of rows usable with theme('table'). + */ +function diff_get_rows($a, $b, $show_header = FALSE, &$line_stats = NULL) { + $a = is_array($a) ? $a : explode("\n", $a); + $b = is_array($b) ? $b : explode("\n", $b); + + if (!isset($line_stats)) { + $line_stats = array( + 'counter' => array('x' => 0, 'y' => 0), + 'offset' => array('x' => 0, 'y' => 0), + ); + } + $formatter = new DrupalDiffFormatter(); + // Header is the line counter. + $formatter->show_header = $show_header; + $formatter->line_stats = &$line_stats; + $diff = new Diff($a, $b); + return $formatter->format($diff); +} + +/** + * Render and markup a diff of two strings into HTML markup. + * + * @param string $a + * The source string to compare from. + * @param string $b + * The target string to compare to. + * + * @return string + * String containing HTML markup. + */ +function diff_get_inline($a, $b) { + $diff = new DrupalDiffInline($a, $b); + return $diff->render(); +} + +/** + * Form builder: Inline diff controls. + */ +function diff_inline_form($form, $form_state, $node, $revisions) { + $form = array(); + $form['node'] = array( + '#type' => 'value', + '#value' => $node, + ); + $form['revision'] = array( + '#type' => 'select', + '#options' => array(0 => t('- No highlighting -')), + '#default_value' => (arg(2) === 'revisions' && arg(3) === $node->vid) ? $node->vid : 0, + '#ajax' => array( + 'callback' => 'diff_inline_ajax', + 'wrapper' => "node-{$node->nid}", + 'method' => 'replace', + ), + ); + foreach ($revisions as $revision) { + $form['revision']['#options'][$revision->vid] = t('@revision by @name', array( + '@revision' => format_date($revision->timestamp, 'short'), + '@name' => format_username($revision), + )); + } + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('View'), + '#submit' => array('diff_inline_form_submit'), + '#attributes' => array('class' => array('diff-js-hidden')), + ); + return $form; +} + +/** + * AHAH callback for rendering the inline diff of a node. + */ +function diff_inline_ajax($form, $form_state) { + module_load_include('inc', 'diff', 'diff.pages'); + $node = $form['node']['#value']; + $vid = isset($form_state['values']['revision']) ? $form_state['values']['revision'] : 0; + return "<div id='node-{$node->nid}'>" . diff_inline_show($node, $vid) . "</div>"; +} + +/** + * Form submission handler for diff_inline_form() for JS-disabled clients. + */ +function diff_inline_form_submit(&$form, &$form_state) { + if (isset($form_state['values']['revision'], $form_state['values']['node'])) { + $node = $form_state['values']['node']; + $vid = $form_state['values']['revision']; + $form_state['redirect'] = "node/{$node->nid}/revisions/{$vid}/view"; + } +} + +/** + * A helper function to normalise system differences. + * + * This handles differences in: + * - line endings: Mac, Windows and UNIX all use different line endings. + */ +function diff_normalise_text($text) { + $text = str_replace(array("\r\n", "\r"), "\n", $text); + return $text; +} + +/** + * A wrapper function for filter_xss() to exclude all tags. + */ +function diff_filter_xss($string) { + return filter_xss($string, array()); +} + +/** + * Helper function to load any CSS or JScript files required by a page or form. + */ +function diff_build_attachments($jscript = FALSE) { + $attachments = array(); + $theme = variable_get('diff_theme', 'default'); + if ($theme) { + $attachments['css'] = array( + drupal_get_path('module', 'diff') . "/css/diff.{$theme}.css", + ); + } + $type = variable_get('diff_radio_behavior', 'simple'); + if ($jscript && $type) { + $attachments['js'] = array( + drupal_get_path('module', 'diff') . "/js/diff.js", + array( + 'data' => array('diffRevisionRadios' => $type), + 'type' => 'setting', + ), + ); + } + return $attachments; +} diff --git a/profiles/wcm_base/modules/contrib/diff/diff.pages.inc b/profiles/wcm_base/modules/contrib/diff/diff.pages.inc new file mode 100644 index 00000000..1cd14419 --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/diff.pages.inc @@ -0,0 +1,632 @@ +<?php + +/** + * @file + * Menu callbacks for hook_menu(). + */ + +/** + * Menu callback - show latest diff for a given node. + */ +function diff_latest($node) { + $revisions = node_revision_list($node); + $new = array_shift($revisions); + $old = array_shift($revisions); + drupal_goto("node/{$node->nid}/revisions/view/{$old->vid}/{$new->vid}"); +} + +/** + * Menu callback - an overview table of older revisions. + * + * Generate an overview table of older revisions of a node and provide + * an input form to select two revisions for a comparison. + */ +function diff_diffs_overview($node) { + drupal_set_title(t('Revisions for %title', array('%title' => $node->title)), PASS_THROUGH); + return drupal_get_form('diff_node_revisions', $node); +} + +/** + * Input form to select two revisions. + */ +function diff_node_revisions($form, $form_state, $node) { + $form['nid'] = array( + '#type' => 'hidden', + '#value' => $node->nid, + ); + + $revision_list = node_revision_list($node); + + if (count($revision_list) > REVISION_LIST_SIZE) { + // If the list of revisions is longer than the number shown on one page + // split the array. + $page = isset($_GET['page']) ? $_GET['page'] : '0'; + $revision_chunks = array_chunk(node_revision_list($node), REVISION_LIST_SIZE); + $revisions = $revision_chunks[$page]; + // Set up global pager variables as would 'pager_query' do. + // These variables are then used in the theme('pager') call later. + global $pager_page_array, $pager_total, $pager_total_items; + $pager_total_items[0] = count($revision_list); + $pager_total[0] = ceil(count($revision_list) / REVISION_LIST_SIZE); + $pager_page_array[0] = max(0, min($page, ((int) $pager_total[0]) - 1)); + } + else { + $revisions = $revision_list; + } + + $revert_permission = FALSE; + if ((user_access('revert revisions') || user_access('administer nodes')) && node_access('update', $node)) { + $revert_permission = TRUE; + } + $delete_permission = FALSE; + if ((user_access('delete revisions') || user_access('administer nodes')) && node_access('delete', $node)) { + $delete_permission = TRUE; + } + + foreach ($revisions as $revision) { + $operations = array(); + $revision_ids[$revision->vid] = ''; + + $revision_log = ($revision->log != '') ? '<p class="revision-log">' . filter_xss($revision->log) . '</p>' : ''; + if ($revision->current_vid > 0) { + $form['info'][$revision->vid] = array( + '#markup' => t('!date by !username', array( + '!date' => l(format_date($revision->timestamp, 'small'), "node/$node->nid"), + '!username' => theme('username', array('account' => $revision)))) . $revision_log, + ); + } + else { + $diff_date = l(format_date($revision->timestamp, 'small'), "node/$node->nid/revisions/$revision->vid/view"); + $form['info'][$revision->vid] = array( + '#markup' => t('!date by !username', array( + '!date' => $diff_date, + '!username' => theme('username', array('account' => $revision))) + ) . $revision_log, + ); + if ($revert_permission) { + $operations[] = array( + '#markup' => l(t('Revert'), "node/$node->nid/revisions/$revision->vid/revert"), + ); + } + if ($delete_permission) { + $operations[] = array( + '#markup' => l(t('Delete'), "node/$node->nid/revisions/$revision->vid/delete"), + ); + } + // Set a dummy, even if the user has no permission for the other + // operations, so that we can check if the operations array is + // empty to know if the row denotes the current revision. + $operations[] = array(); + } + $form['operations'][$revision->vid] = $operations; + + } + $new_vid = key($revision_ids); + next($revision_ids); + $old_vid = key($revision_ids); + $form['diff']['old'] = array( + '#type' => 'radios', + '#options' => $revision_ids, + '#default_value' => $old_vid, + ); + $form['diff']['new'] = array( + '#type' => 'radios', + '#options' => $revision_ids, + '#default_value' => $new_vid, + ); + + $form['submit'] = array('#type' => 'submit', '#value' => t('Compare')); + + if (count($revision_list) > REVISION_LIST_SIZE) { + $form['#suffix'] = theme('pager'); + } + $form['#attached'] = diff_build_attachments(TRUE); + return $form; +} + +/** + * Submit code for input form to select two revisions. + */ +function diff_node_revisions_submit($form, &$form_state) { + // The ids are ordered so the old revision is always on the left. + $old_vid = min($form_state['values']['old'], $form_state['values']['new']); + $new_vid = max($form_state['values']['old'], $form_state['values']['new']); + $form_state['redirect'] = 'node/' . $form_state['values']['nid'] . '/revisions/view/' . $old_vid . '/' . $new_vid; +} + +/** + * Validation for input form to select two revisions. + */ +function diff_node_revisions_validate($form, &$form_state) { + $old_vid = $form_state['values']['old']; + $new_vid = $form_state['values']['new']; + if ($old_vid == $new_vid || !$old_vid || !$new_vid) { + form_set_error('diff', t('Select different revisions to compare.')); + } +} + +/** + * Create a comparison for the node between versions 'old_vid' and 'new_vid'. + * + * @param object $node + * Node on which to perform comparison + * @param integer $old_vid + * Version ID of the old revision. + * @param integer $new_vid + * Version ID of the new revision. + */ +function diff_diffs_show($node, $old_vid, $new_vid, $state = NULL) { + // Attaches the CSS. + $build['#attached'] = diff_build_attachments(); + + $default_state = variable_get('diff_default_state_node', 'raw'); + if (empty($state)) { + $state = $default_state; + } + $state = str_replace('-', '_', $state); + if (!array_key_exists($state, diff_available_states())) { + $state = $default_state; + } + + // Same title as the 'Revisions' tab. Blocked by non-page requests. + if (node_is_page($node)) { + drupal_set_title(t('Revisions for %title', array('%title' => $node->title)), PASS_THROUGH); + } + $node_revisions = node_revision_list($node); + + $old_node = node_load($node->nid, $old_vid); + $new_node = node_load($node->nid, $new_vid); + + // Generate table header (date, username, log message). + $old_header = t('!date by !username', array( + '!date' => l(format_date($old_node->revision_timestamp), "node/$node->nid/revisions/$old_node->vid/view", array('absolute' => 1)), + '!username' => theme('username', array('account' => $node_revisions[$old_vid])), + )); + $new_header = t('!date by !username', array( + '!date' => l(format_date($new_node->revision_timestamp), "node/$node->nid/revisions/$new_node->vid/view", array('absolute' => 1)), + '!username' => theme('username', array('account' => $node_revisions[$new_vid])), + )); + + $old_log = $old_node->log != '' ? '<p class="revision-log">' . filter_xss($old_node->log) . '</p>' : ''; + $new_log = $new_node->log != '' ? '<p class="revision-log">' . filter_xss($new_node->log) . '</p>' : ''; + + // Generate previous diff/next diff links. + $nav_suffix = ($default_state != $state) ? '/' . str_replace('_', '-', $state) : ''; + $next_vid = _diff_get_next_vid($node_revisions, $new_vid); + if ($next_vid) { + $next_link = l(t('Next difference >'), 'node/' . $node->nid . '/revisions/view/' . $new_vid . '/' . $next_vid . $nav_suffix, array('absolute' => 1)); + } + else { + $next_link = ''; + } + $prev_vid = _diff_get_previous_vid($node_revisions, $old_vid); + if ($prev_vid) { + $prev_link = l(t('< Previous difference'), 'node/' . $node->nid . '/revisions/view/' . $prev_vid . '/' . $old_vid . $nav_suffix, array('absolute' => 1)); + } + else { + $prev_link = ''; + } + + $header = _diff_default_header($old_header, $new_header); + $rows = array(); + if ($old_log || $new_log) { + $rows['logs'] = array( + array( + 'data' => $old_log, + 'colspan' => 2, + ), + array( + 'data' => $new_log, + 'colspan' => 2, + ), + ); + } + $rows['navigation'] = array( + array( + 'data' => $prev_link, + 'class' => array('diff-prevlink'), + 'colspan' => 2, + ), + array( + 'data' => $next_link, + 'class' => array('diff-nextlink'), + 'colspan' => 2, + ), + ); + + $links = array(); + foreach (diff_available_states('node') as $alternative_state => $label) { + if ($alternative_state == $state) { + // @todo: Should we show both or just alternatives? + } + $links[$alternative_state] = array( + 'title' => $label, + 'href' => "node/{$node->nid}/revisions/view/{$old_vid}/{$new_vid}" . ($alternative_state == $default_state ? '' : '/' . str_replace('_', '-', $alternative_state)), + ); + } + if (count($links) > 1) { + $state_links = theme('links', array( + 'links' => $links, + 'attributes' => array('class' => array('links', 'inline')), + )); + $rows['states'] = array( + array( + 'data' => $state_links, + 'class' => 'diff-links', + 'colspan' => 4, + ), + ); + } + $rows = array_merge($rows, _diff_body_rows($old_node, $new_node, $state)); + + $build['diff_table'] = array( + '#theme' => 'table__diff__standard', + '#header' => $header, + '#rows' => $rows, + '#attributes' => array('class' => array('diff')), + '#colgroups' => _diff_default_cols(), + '#sticky' => FALSE, + ); + + // Allow users to hide or set the display mode of the preview. + if (node_is_page($node) && $view_mode = variable_get('diff_view_mode_preview_node_' . $new_node->type, 'full')) { + $header = ''; + if ($node->vid == $new_vid) { + $header .= '<div class="diff-section-title">' . t('Current revision:') . '</div>'; + } + else { + $header .= '<div class="diff-section-title">' . t('Revision of @new_date:', array('@new_date' => format_date($new_node->revision_timestamp))) . '</div>'; + } + $build['diff_preview']['header']['#markup'] = $header; + // Don't include node links or comments when viewing the diff. + $build['diff_preview']['content'] = node_view($new_node, $view_mode); + if (isset($build['diff_preview']['content']['links'])) { + unset($build['diff_preview']['content']['links']); + } + if (isset($build['diff_preview']['content']['comments'])) { + unset($build['diff_preview']['content']['comments']); + } + } + return $build; +} + +/** + * Creates an array of rows which represent the difference between nodes. + * + * @param object $old_node + * Node for comparison which will be displayed on the left side. + * @param object $new_node + * Node for comparison which will be displayed on the right side. + * @param boolean $state + * The state to render for the diff. + */ +function _diff_body_rows($old_node, $new_node, $state = 'raw') { + // This is an unique index only, so no need for drupal_static(). + static $table_row_counter = 0; + + if ($theme = variable_get('diff_theme', 'default')) { + drupal_add_css(drupal_get_path('module', 'diff') . "/css/diff.{$theme}.css"); + } + module_load_include('inc', 'diff', 'includes/node'); + + $rows = array(); + $any_visible_change = FALSE; + $context = array( + 'entity_type' => 'node', + 'states' => array($state), + 'view_mode' => 'diff_standard', + ); + + $node_diffs = diff_compare_entities($old_node, $new_node, $context); + + // Track line numbers between multiple diffs. + $line_stats = array( + 'counter' => array('x' => 0, 'y' => 0), + 'offset' => array('x' => 0, 'y' => 0), + ); + + // Render diffs for each. + foreach ($node_diffs as $node_diff) { + $show_header = !empty($node_diff['#name']); + // These are field level settings. + if ($show_header && isset($node_diff['#settings']['show_header'])) { + $show_header = $show_header && $node_diff['#settings']['show_header']; + } + + // Line counting and line header options. + if (empty($node_diff['#settings']['line_counter'])) { + $line_counter = FALSE; + } + else { + $line_counter = $node_diff['#settings']['line_counter']; + } + // Every call to 'line' resets the counters. + if ($line_counter) { + $line_stats['counter']['x'] = 0; + $line_stats['counter']['y'] = 0; + if ($line_counter == 'line' && 0) { + $line_stats['offset']['x'] = 0; + $line_stats['offset']['y'] = 0; + } + $line_stats_ref = $line_stats; + } + else { + $line_stats_ref = NULL; + } + + list($old, $new) = diff_extract_state($node_diff, $state); + if ($node_diff_rows = diff_get_rows($old, $new, $line_counter && $line_counter != 'hidden', $line_stats_ref)) { + if ($line_counter && $line_counter != 'line') { + $line_stats['offset']['x'] += $line_stats_ref['counter']['x']; + $line_stats['offset']['y'] += $line_stats_ref['counter']['y']; + } + if ($show_header) { + $rows['diff-header-' . $table_row_counter++] = array( + array( + 'data' => t('Changes to %name', array('%name' => $node_diff['#name'])), + 'class' => 'diff-section-title', + 'colspan' => 4, + ), + ); + } + // To avoid passing counter to the Diff engine, index rows manually here + // to allow modules to interact with the table. i.e. no array_merge(). + foreach ($node_diff_rows as $row) { + $rows['diff-row-' . $table_row_counter++] = $row; + } + $any_visible_change = TRUE; + } + } + if (!$any_visible_change) { + $rows['diff-empty-' . $table_row_counter++] = array( + array( + 'data' => t('No visible changes'), + 'class' => 'diff-section-title', + 'colspan' => 4, + ), + ); + // @todo: revise this. + // Needed to keep safari happy. + $rows['diff-empty-' . $table_row_counter++] = array( + array('data' => ''), + array('data' => ''), + array('data' => ''), + array('data' => ''), + ); + } + + return $rows; +} + +/** + * Generic callback to compare two entities. + */ +function diff_compare_entities($left_entity, $right_entity, $context) { + $entity_type = $context['entity_type']; + list(, , $bundle) = entity_extract_ids($entity_type, $right_entity); + $context['bundle'] = $bundle; + $context['old_entity'] = $left_entity; + $context['new_entity'] = $right_entity; + $context += array( + 'states' => array('raw'), + 'view_mode' => FALSE, + 'language' => LANGUAGE_NONE, + ); + + $diff = module_invoke_all('entity_diff', $left_entity, $right_entity, $context); + + // Allow other modules to interact directly with the results. + drupal_alter('entity_diff', $diff, $context); + + // We start off assuming all form elements are in the correct order. + $diff['#sorted'] = TRUE; + + // Field rows. Recurse through all child elements. + $count = 0; + foreach (element_children($diff) as $key) { + if (!isset($diff[$key]['#states'])) { + $diff[$key]['#states'] = array(); + } + + // Ensure that the element follows the new #states format. + if (isset($diff[$key]['#old'])) { + $diff[$key]['#states']['raw']['#old'] = $diff[$key]['#old']; + unset($diff[$key]['#old']); + } + if (isset($diff[$key]['#new'])) { + $diff[$key]['#states']['raw']['#new'] = $diff[$key]['#new']; + unset($diff[$key]['#new']); + } + + // If requested, we can convert the . + foreach (array('raw', 'rendered') as $state) { + if (in_array($state . '_plain', $context['states'])) { + diff_markdown_state($diff[$key], $state); + } + } + + // Assign a decimal placeholder weight to preserve original array order. + if (!isset($diff[$key]['#weight'])) { + $diff[$key]['#weight'] = $count / 1000; + } + else { + // If one child element has a weight then we will need to sort later. + unset($diff['#sorted']); + } + $count++; + } + + // One of the children has a #weight. + if (!isset($diff['#sorted'])) { + uasort($diff, 'element_sort'); + } + + // Process the array and get line counts per field. + array_walk($diff, 'diff_process_state_lines'); + + return $diff; +} + +function diff_process_state_lines(&$diff, $key) { + foreach ($diff['#states'] as $state => $data) { + if (isset($data['#old'])) { + if (is_string($data['#old'])) { + $diff['#states'][$state]['#old'] = explode("\n", $data['#old']); + } + $diff['#states'][$state]['#count_old'] = count($diff['#states'][$state]['#old']); + } + else { + $diff['#states'][$state]['#count_old'] = 0; + } + if (isset($data['#new'])) { + if (is_string($data['#new'])) { + $diff['#states'][$state]['#new'] = explode("\n", $data['#new']); + } + $diff['#states'][$state]['#count_new'] = count($diff['#states'][$state]['#new']); + } + else { + $diff['#states'][$state]['#count_new'] = 0; + } + } +} + +/** + * Helper function to render plain states from the corresponding raw state. + * + * @param array $diff + * The Diff Engine output array. + * @param string $state + * The state to markdown. + */ +function diff_markdown_state(&$diff, $state) { + list($plain_old, $plain_new) = diff_extract_state($diff, $state . '_plain'); + list($old, $new) = diff_extract_state($diff, $state); + $markdown = FALSE; + if (isset($diff['#settings']) && !empty($diff['#settings']['markdown'])) { + if (function_exists($diff['#settings']['markdown'])) { + $markdown = $diff['#settings']['markdown']; + } + } + + if (!isset($plain_old) && isset($old)) { + if (is_array($old)) { + $diff['#states'][$state . '_plain']['#old'] = $markdown ? array_map($markdown, $old) : $old; + } + else { + $diff['#states'][$state . '_plain']['#old'] = $markdown ? $markdown($old) : $old; + } + } + if (!isset($plain_new) && isset($new)) { + if (is_array($new)) { + $diff['#states'][$state . '_plain']['#new'] = $markdown ? array_map($markdown, $new) : $new; + } + else { + $diff['#states'][$state . '_plain']['#new'] = $markdown ? $markdown($new) : $new; + } + } +} + +/** + * Get the entry in the revisions list after $vid. + * + * @param array $node_revisions + * Array of node revision IDs in descending order. + * @param int $vid + * Version ID to look for. + * + * @return boolean|integer + * Returns FALSE if $vid is the last entry. + */ +function _diff_get_next_vid($node_revisions, $vid) { + $previous = NULL; + foreach ($node_revisions as $revision) { + if ($revision->vid == $vid) { + return ($previous ? $previous->vid : FALSE); + } + $previous = $revision; + } + return FALSE; +} + +/** + * Get the entry in the revision list before $vid. + * + * @param array $node_revisions + * Array of node revision IDs in descending order. + * @param integer $vid + * Version ID to look for. + * + * @return boolean|integer + * Returns FALSE if $vid is the first entry. + */ +function _diff_get_previous_vid($node_revisions, $vid) { + $previous = NULL; + foreach ($node_revisions as $revision) { + if ($previous && $previous->vid == $vid) { + return $revision->vid; + } + $previous = $revision; + } + return FALSE; +} + +/** + * Helper function to create default 'cols' array for diff table. + */ +function _diff_default_cols() { + return array( + array( + array( + 'class' => 'diff-marker', + ), + array( + 'class' => 'diff-content', + ), + array( + 'class' => 'diff-marker', + ), + array( + 'class' => 'diff-content', + ), + ), + ); +} + +/** + * Helper function to create default 'header' array for diff table. + */ +function _diff_default_header($old_header = '', $new_header = '') { + return array( + array( + 'data' => $old_header, + 'colspan' => 2, + ), + array( + 'data' => $new_header, + 'colspan' => 2, + ), + ); +} + +/** + * Show the inline diff for a given node, vid. + * + * If vid = 0 or no previous vid exists for the given revision returns the + * normally rendered content of the specified revision. + */ +function diff_inline_show($node, $vid = 0, $metadata = TRUE) { + $new_node = $vid ? node_load($node->nid, $vid, TRUE) : clone $node; + node_build_content($new_node); + $new = drupal_render($new_node->content); + + $old = $vid ? _diff_get_previous_vid(node_revision_list($node), $vid) : 0; + if ($old) { + $old_node = node_load($node->nid, $old, TRUE); + node_build_content($old_node); + $old = drupal_render($old_node->content); + $output = $metadata ? theme('diff_inline_metadata', array('node' => $new_node)) : ''; + $output .= diff_get_inline($old, $new); + return $output; + } + return $new; +} diff --git a/profiles/wcm_base/modules/contrib/diff/diff.theme.inc b/profiles/wcm_base/modules/contrib/diff/diff.theme.inc new file mode 100644 index 00000000..96d20b3a --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/diff.theme.inc @@ -0,0 +1,149 @@ +<?php + +/** + * @file + * Themeable function callbacks for diff.module. + */ + +/** + * Theme function to display the revisions formular. + */ +function theme_diff_node_revisions($vars) { + $form = $vars['form']; + $output = ''; + + // Overview table: + $header = array( + t('Revision'), + array('data' => drupal_render($form['submit']), 'colspan' => 2), + array('data' => t('Operations'), 'colspan' => 2), + ); + if (isset($form['info']) && is_array($form['info'])) { + foreach (element_children($form['info']) as $key) { + $row = array(); + if (isset($form['operations'][$key][0])) { + // Note: even if the commands for revert and delete are not permitted, + // the array is not empty since we set a dummy in this case. + $row[] = drupal_render($form['info'][$key]); + $row[] = drupal_render($form['diff']['old'][$key]); + $row[] = drupal_render($form['diff']['new'][$key]); + $row[] = drupal_render($form['operations'][$key][0]); + $row[] = drupal_render($form['operations'][$key][1]); + $rows[] = array( + 'data' => $row, + 'class' => array('diff-revision'), + ); + } + else { + // The current revision (no commands to revert or delete). + $row[] = array( + 'data' => drupal_render($form['info'][$key]), + 'class' => array('revision-current'), + ); + $row[] = array( + 'data' => drupal_render($form['diff']['old'][$key]), + 'class' => array('revision-current'), + ); + $row[] = array( + 'data' => drupal_render($form['diff']['new'][$key]), + 'class' => array('revision-current'), + ); + $row[] = array( + 'data' => t('current revision'), + 'class' => array('revision-current'), + 'colspan' => '2', + ); + $rows[] = array( + 'data' => $row, + 'class' => array('error diff-revision'), + ); + } + } + } + $output .= theme('table__diff__revisions', array( + 'header' => $header, + 'rows' => $rows, + 'sticky' => FALSE, + 'attributes' => array('class' => 'diff-revisions'), + )); + + $output .= drupal_render_children($form); + return $output; +} + +/** + * Theme functions + */ + +/** + * Theme function for a header line in the diff. + */ +function theme_diff_header_line($vars) { + return '<strong>' . t('Line @lineno', array('@lineno' => $vars['lineno'])) . '</strong>'; +} + +/** + * Theme function for a content line in the diff. + */ +function theme_diff_content_line($vars) { + return '<div>' . $vars['line'] . '</div>'; +} + +/** + * Theme function for an empty line in the diff. + */ +function theme_diff_empty_line($vars) { + return $vars['line']; +} + +/** + * Theme function for inline diff form. + */ +function theme_diff_inline_form($vars) { + if ($theme = variable_get('diff_theme', 'default')) { + drupal_add_css(drupal_get_path('module', 'diff') . "/css/diff.{$theme}.css"); + } + return drupal_render_children($vars['form']); +} + +/** + * Display inline diff metadata. + */ +function theme_diff_inline_metadata($vars) { + if ($theme = variable_get('diff_theme', 'default')) { + drupal_add_css(drupal_get_path('module', 'diff') . "/css/diff.{$theme}.css"); + } + $node = $vars['node']; + + $output = "<div class='diff-inline-metadata clear-block'>"; + $output .= "<div class='diff-inline-byline'>"; + $output .= t('Updated by !name on @date', array( + '!name' => theme('username', array('account' => user_load($node->revision_uid))), + '@date' => format_date($node->revision_timestamp, 'small'), + )); + $output .= "</div>"; + $output .= "<div class='diff-inline-legend clear-block'>"; + $output .= "<label>" . t('Legend') . "</label>"; + $output .= theme('diff_inline_chunk', array('text' => t('Added'), 'type' => 'add')); + $output .= theme('diff_inline_chunk', array('text' => t('Changed'), 'type' => 'change')); + $output .= theme('diff_inline_chunk', array('text' => t('Deleted'), 'type' => 'delete')); + $output .= "</div>"; + $output .= "</div>"; + return $output; +} + +/** + * Theme a span of changed text in an inline diff display. + */ +function theme_diff_inline_chunk($vars) { + switch ($vars['type']) { + case 'add': + return "<span class='diff-added'>{$vars['text']}</span>"; + case 'change': + return "<span class='diff-changed'>{$vars['text']}</span>"; + case 'delete': + return "<span class='diff-deleted'>{$vars['text']}</span>"; + default: + return $vars['text']; + } +} diff --git a/profiles/wcm_base/modules/contrib/diff/diff.tokens.inc b/profiles/wcm_base/modules/contrib/diff/diff.tokens.inc new file mode 100644 index 00000000..96dbd80a --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/diff.tokens.inc @@ -0,0 +1,63 @@ +<?php + +/** + * @file + * Builds placeholder replacement tokens for diff-related data. + */ + +/** + * Implements hook_token_info(). + */ +function diff_token_info() { + $node['diff'] = array( + 'name' => t('Latest differences'), + 'description' => t('The differences between the current revision and the previous revision of this node.'), + ); + $node['diff-markdown'] = array( + 'name' => t('Latest differences (marked down)'), + 'description' => t('The differences between the current revision and the previous revision of this node, but with a marked-down form of each revision used for comparison.'), + ); + + return array( + 'tokens' => array('node' => $node), + ); +} + +/** + * Implements hook_tokens(). + */ +function diff_tokens($type, $tokens, array $data = array(), array $options = array()) { + $sanitize = !empty($options['sanitize']); + + $replacements = array(); + + if ($type == 'node' && !empty($data['node'])) { + $node = $data['node']; + foreach ($tokens as $name => $original) { + switch ($name) { + // Basic diff standard comparison information. + case 'diff': + case 'diff-markdown': + $revisons = node_revision_list($node); + if (count($revisons) == 1) { + $replacements[$original] = t('(No previous revision available.)'); + } + else { + module_load_include('inc', 'diff', 'diff.pages'); + $old_vid = _diff_get_previous_vid($revisons, $node->vid); + $state = $name == 'diff' ? 'raw' : 'raw_plain'; + $build = diff_diffs_show($node, $old_vid, $node->vid, $state); + unset($build['diff_table']['#rows']['states']); + unset($build['diff_table']['#rows']['navigation']); + unset($build['diff_preview']); + + $output = drupal_render_children($build); + $replacements[$original] = $sanitize ? check_plain($output) : $output; + } + break; + + } + } + } + return $replacements; +} diff --git a/profiles/wcm_base/modules/contrib/diff/includes/file.inc b/profiles/wcm_base/modules/contrib/diff/includes/file.inc new file mode 100644 index 00000000..678ff466 --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/includes/file.inc @@ -0,0 +1,111 @@ +<?php + +/** + * @file + * Provide diff field functions for the file module. + */ + +/** + * Diff field callback for preloading file entities. + */ +function file_field_diff_view_prepare(&$old_items, &$new_items, $context) { + $fids = array(); + foreach (array_merge_recursive($old_items, $new_items) as $info) { + $fids[$info['fid']] = $info['fid']; + } + $files = file_load_multiple($fids); + + foreach ($old_items as $delta => $info) { + $old_items[$delta]['file'] = isset($files[$info['fid']]) ? $files[$info['fid']] : NULL; + } + foreach ($new_items as $delta => $info) { + $new_items[$delta]['file'] = isset($files[$info['fid']]) ? $files[$info['fid']] : NULL; + } +} + +/** + * Diff field callback for parsing file field comparative values. + */ +function file_field_diff_view($items, $context) { + $field = $context['field']; + $instance = $context['instance']; + $settings = $context['settings']; + + $diff_items = array(); + foreach ($items as $delta => $item) { + if (isset($item['file'])) { + $output = array(); + + // We populate as much as possible to allow the best flexability in any + // string overrides. + $t_args = array(); + foreach ($item as $key => $value) { + if (is_scalar($value)) { + $t_args['!' . $key] = $value; + } + } + // Some states do not have the file properties in the item, so put these + // out of the main file object. + if (!empty($item['file'])) { + $file_values = (array) $item['file']; + foreach ($file_values as $key => $value) { + if (is_scalar($value) && !isset($t_args['!' . $key])) { + $t_args['!' . $key] = $value; + } + } + } + + $output['file'] = t('File: !filename', $t_args); + if ($settings['compare_description_field'] && !empty($instance['settings']['description_field'])) { + if (!empty($item['description'])) { + $output['description'] = t('Description: !description', $t_args); + } + } + if ($settings['show_id']) { + $output['fid'] = t('File ID: !fid', $t_args); + } + if ($settings['compare_display_field'] && !empty($field['settings']['display_field'])) { + $output['display'] = $item['display'] ? t('Displayed') : t('Hidden'); + } + $diff_items[$delta] = implode('; ', $output); + } + } + + return $diff_items; +} + +/** + * Provide default field comparison options. + */ +function file_field_diff_default_options($field_type) { + return array( + 'show_id' => 0, + 'compare_display_field' => 0, + 'compare_description_field' => 0, + ); +} + +/** + * Provide a form for setting the field comparison options. + */ +function file_field_diff_options_form($field_type, $settings) { + $options_form = array(); + $options_form['show_id'] = array( + '#type' => 'checkbox', + '#title' => t('Show file ID'), + '#default_value' => $settings['show_id'], + ); + $options_form['compare_description_field'] = array( + '#type' => 'checkbox', + '#title' => t('Compare description field'), + '#default_value' => $settings['compare_description_field'], + '#description' => t('This is only used if the "Enable <em>Description</em> field" is checked in the instance settings.'), + ); + $options_form['compare_display_field'] = array( + '#type' => 'checkbox', + '#title' => t('Compare display state field'), + '#default_value' => $settings['compare_display_field'], + '#description' => t('This is only used if the "Enable <em>Display</em> field" is checked in the field settings.'), + ); + return $options_form; +} diff --git a/profiles/wcm_base/modules/contrib/diff/includes/image.inc b/profiles/wcm_base/modules/contrib/diff/includes/image.inc new file mode 100644 index 00000000..cb93616d --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/includes/image.inc @@ -0,0 +1,112 @@ +<?php + +/** + * @file + * Provide diff field functions for the image module. + */ + +/** + * Diff field callback for preloading the image file entities. + */ +function image_field_diff_view_prepare(&$old_items, &$new_items, $context) { + $fids = array(); + foreach (array_merge_recursive($old_items, $new_items) as $info) { + $fids[$info['fid']] = $info['fid']; + } + $files = file_load_multiple($fids); + + foreach ($old_items as $delta => $info) { + $old_items[$delta]['file'] = isset($files[$info['fid']]) ? $files[$info['fid']] : NULL; + } + foreach ($new_items as $delta => $info) { + $new_items[$delta]['file'] = isset($files[$info['fid']]) ? $files[$info['fid']] : NULL; + } +} + +/** + * Diff field callback for parsing image field comparative values. + */ +function image_field_diff_view($items, $context) { + $instance = $context['instance']; + $settings = $context['settings']; + + $diff_items = array(); + foreach ($items as $delta => $item) { + if (isset($item['file'])) { + $output = array(); + + // We populate as much as possible to allow the best flexability in any + // string overrides. + $t_args = array(); + foreach ($item as $key => $value) { + if (is_scalar($value)) { + $t_args['!' . $key] = $value; + } + } + // Some states do not have the file properties in the item, so put these + // out of the main file object. + if (!empty($item['file'])) { + $file_values = (array) $item['file']; + foreach ($file_values as $key => $value) { + if (is_scalar($value) && !isset($t_args['!' . $key])) { + $t_args['!' . $key] = $value; + } + } + } + + $output[] = t('Image: !filename', $t_args); + if ($settings['compare_alt_field'] && !empty($instance['settings']['alt_field'])) { + if (!empty($item['alt'])) { + $output[] = t('Alt: !alt', $t_args); + } + } + if ($settings['compare_title_field'] && !empty($instance['settings']['title_field'])) { + if (!empty($item['title'])) { + $output[] = t('Title: !title', $t_args); + } + } + if ($settings['show_id']) { + $output[] = t('File ID: !fid', $t_args); + } + $diff_items[$delta] = implode('; ', $output); + } + } + + return $diff_items; +} + +/** + * Provide default field comparison options. + */ +function image_field_diff_default_options($field_type) { + return array( + 'show_id' => 0, + 'compare_alt_field' => 0, + 'compare_title_field' => 0, + ); +} + +/** + * Provide a form for setting the field comparison options. + */ +function image_field_diff_options_form($field_type, $settings) { + $options_form = array(); + $options_form['show_id'] = array( + '#type' => 'checkbox', + '#title' => t('Show image ID'), + '#default_value' => $settings['show_id'], + ); + $options_form['compare_alt_field'] = array( + '#type' => 'checkbox', + '#title' => t('Compare <em>Alt</em> field'), + '#default_value' => $settings['compare_alt_field'], + '#description' => t('This is only used if the "Enable <em>Alt</em> field" is checked in the instance settings.'), + ); + $options_form['compare_title_field'] = array( + '#type' => 'checkbox', + '#title' => t('Compare <em>Title</em> field'), + '#default_value' => $settings['compare_title_field'], + '#description' => t('This is only used if the "Enable <em>Title</em> field" is checked in the instance settings.'), + ); + return $options_form; +} diff --git a/profiles/wcm_base/modules/contrib/diff/includes/list.inc b/profiles/wcm_base/modules/contrib/diff/includes/list.inc new file mode 100644 index 00000000..d1f62e33 --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/includes/list.inc @@ -0,0 +1,71 @@ +<?php + +/** + * @file + * Provide diff field functions for the List module. + */ + +/** + * Diff field callback for parsing list field comparative values. + */ +function list_field_diff_view($items, $context) { + $field = $context['field']; + $instance = $context['instance']; + $settings = $context['settings']; + + $diff_items = array(); + $allowed_values = list_allowed_values($field, $instance, $context['entity_type'], $context['entity']); + foreach ($items as $delta => $item) { + // Fairly complex condition to prevent duplicate "key (key)" type rendering. + if (isset($allowed_values[$item['value']]) && + $allowed_values[$item['value']] != $item['value'] && + strlen($allowed_values[$item['value']])) { + switch ($settings['compare']) { + case 'both': + $diff_items[$delta] = $allowed_values[$item['value']] . ' (' . $item['value'] . ')'; + break; + + case 'label': + $diff_items[$delta] = $allowed_values[$item['value']]; + break; + + default: + $diff_items[$delta] = $item['value']; + break; + + } + } + else { + // If no match was found for the label, fall back to the key. + $diff_items[$delta] = $item['value']; + } + } + return $diff_items; +} + +/** + * Provide default field comparison options. + */ +function list_field_diff_default_options($field_type) { + return array( + 'compare' => 'label', + ); +} + +/** + * Provide a form for setting the field comparison options. + */ +function list_field_diff_options_form($field_type, $settings) { + $options_form = array(); + $options_form['compare'] = array( + '#type' => 'radios', + '#title' => t('Comparison method'), + '#options' => array( + 'label' => t('Label'), + 'key' => t('Key'), + 'both' => t('Label (key)'), + ), + '#default_value' => $settings['compare'], + ); + return $options_form; +} diff --git a/profiles/wcm_base/modules/contrib/diff/includes/node.inc b/profiles/wcm_base/modules/contrib/diff/includes/node.inc new file mode 100644 index 00000000..3f0bca33 --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/includes/node.inc @@ -0,0 +1,107 @@ +<?php + +/** + * @file + * Provide diff functions for the node module. + */ + +/** + * Implements hook_entity_diff(). + * + * This function compares core node properties. This is currently limited to: + * - title: The title of the node. + * + * @param object $old_node + * The older node revision. + * @param object $new_node + * The newer node revision. + * @param array $context + * An associative array containing: + * - entity_type: The entity type; e.g., 'node' or 'user'. + * - old_entity: The older entity. + * - new_entity: The newer entity. + * - view_mode: The view mode to use. Defaults to FALSE. If no view mode is + * given, the recommended fallback view mode is 'default'. + * - states: An array of view states. These could be one of: + * - raw: The raw value of the diff, the classic 7.x-2.x view. + * - rendered: The rendered HTML as determined by the view mode. Only + * return markup for this state if the value is normally shown + * by this view mode. The user will most likely be able to see + * the raw or raw_plain state, so this is optional. + * + * The rendering state is a work in progress. + * + * Conditionally, you can get these states, but setting these will override + * the user selectable markdown method. + * + * - raw_plain: As raw, but text should be markdowned. + * - rendered_plain: As rendered, but text should be markdowned. + * + * @return array + * An associative array of values keyed by the entity property. + * + * This is effectively an unnested Form API-like structure. + * + * States are returned as follows: + * + * $results['line'] = array( + * '#name' => t('Line'), + * '#states' => array( + * 'raw' => array( + * '#old' => '<p class="line">This was the old line number [tag].</p>', + * '#new' => '<p class="line">This is the new line [tag].</p>', + * ), + * 'rendered' => array( + * '#old' => '<p class="line">This was the old line number <span class="line-number">57</span>.</p>', + * '#new' => '<p class="line">This is the new line <span class="line-number">57</span>.</p>', + * ), + * ), + * ); + * + * For backwards compatability, no changes are required to support states, + * but it is recommended to provide a better UI for end users. + * + * For example, the following example is equivalent to returning the raw + * state from the example above. + * + * $results['line'] = array( + * '#name' => t('Line'), + * '#old' => '<p class="line">This was the old line number [tag].</p>', + * '#new' => '<p class="line">This is the new line [tag].</p>', + * ); + */ +function node_entity_diff($old_node, $new_node, $context) { + $result = array(); + if ($context['entity_type'] == 'node') { + $type = node_type_get_type($new_node); + $result['title'] = array( + '#name' => $type->title_label, + '#states' => array(), + '#weight' => -5, + '#settings' => array( + // Global setting - 'diff_show_header_' . $entity_type + 'show_header' => variable_get('diff_show_header_node', 1), + ), + ); + foreach ($context['states'] as $state) { + switch ($state) { + case 'rendered': + $result['title']['#states'][$state] = array( + '#old' => l($old_node->title, 'node/' . $old_node->title), + '#new' => l($new_node->title, 'node/' . $new_node->title), + ); + break; + + // We specify a default so that the title is allows compared. + case 'raw': + default: + $result['title']['#states'][$state] = array( + '#old' => array($old_node->title), + '#new' => array($new_node->title), + ); + break; + } + } + } + return $result; +} diff --git a/profiles/wcm_base/modules/contrib/diff/includes/number.inc b/profiles/wcm_base/modules/contrib/diff/includes/number.inc new file mode 100644 index 00000000..45e05133 --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/includes/number.inc @@ -0,0 +1,17 @@ +<?php + +/** + * @file + * Provide diff field functions for the Number module. + */ + +/** + * Diff field callback for parsing number field comparative values. + */ +function number_field_diff_view($items, $context) { + $diff_items = array(); + foreach ($items as $delta => $item) { + $diff_items[$delta] = $item['value']; + } + return $diff_items; +} diff --git a/profiles/wcm_base/modules/contrib/diff/includes/taxonomy.inc b/profiles/wcm_base/modules/contrib/diff/includes/taxonomy.inc new file mode 100644 index 00000000..5765c9c2 --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/includes/taxonomy.inc @@ -0,0 +1,107 @@ +<?php + +/** + * @file + * Implements pusdeo-hook hook_field_diff_view() for the Taxonomy module. + */ + +/** + * Diff field callback for preloading term entities. + */ +function taxonomy_field_diff_view_prepare(&$old_items, &$new_items, $context) { + $tids = array(); + foreach (array_merge_recursive($old_items, $new_items) as $info) { + $tids[$info['tid']] = $info['tid']; + } + $terms = taxonomy_term_load_multiple($tids); + foreach ($old_items as $delta => $info) { + $old_items[$delta]['term'] = isset($terms[$info['tid']]) ? $terms[$info['tid']] : NULL; + } + foreach ($new_items as $delta => $info) { + $new_items[$delta]['term'] = isset($terms[$info['tid']]) ? $terms[$info['tid']] : NULL; + } +} + +/** + * Diff field callback for parsing term field comparative values. + */ +function taxonomy_field_diff_view($items, $context) { + $settings = $context['settings']; + $instance = $context['instance']; + + $diff_items = array(); + foreach ($items as $delta => $item) { + if (!empty($item['tid'])) { + if ($item['tid'] == 'autocreate') { + $diff_items[$delta] = t('!term_name (new)', array('!term_name' => $item['name'])); + } + elseif (empty($item['term'])) { + $diff_items[$delta] = t('Missing term reference (!tid)', array('!tid' => $item['tid'])); + } + else { + $output = array(); + $output['name'] = $item['term']->name; + if ($settings['show_id']) { + $output['tid'] = t('Term ID: !tid', array('!tid' => $item['term']->tid)); + } + $diff_items[$delta] = implode('; ', $output); + } + } + } + if (!empty($settings['sort']) && !empty($diff_items)) { + if ($settings['sort'] == DIFF_SORT_VALUE || $instance['widget']['type'] == 'taxonomy_autocomplete') { + usort($diff_items, 'uasort_taxonomy_field_diff_terms'); + } + } + return $diff_items; +} + +/** + * Helper function for sorting terms. + */ +function uasort_taxonomy_field_diff_terms($a, $b) { + // We need to use t() to test for string overrides. + $missing_text = t('Missing term reference'); + $a_missing = strpos($a, $missing_text) === 0; + $b_missing = strpos($b, $missing_text) === 0; + if ($a_missing && $b_missing) { + return strnatcmp($a, $b); + } + elseif ($a_missing xor $b_missing) { + return $a_missing ? 100 : -100; + } + return strnatcmp($a, $b); +} + +/** + * Provide default field comparison options. + */ +function taxonomy_field_diff_default_options($field_type) { + return array( + 'show_id' => 0, + 'sort' => DIFF_SORT_CUSTOM, + ); +} + +/** + * Provide a form for setting the field comparison options. + */ +function taxonomy_field_diff_options_form($field_type, $settings) { + $options_form = array(); + $options_form['show_id'] = array( + '#type' => 'checkbox', + '#title' => t('Show term ID'), + '#default_value' => $settings['show_id'], + ); + $options_form['sort'] = array( + '#type' => 'radios', + '#title' => t('Sort'), + '#options' => array( + DIFF_SORT_NONE => t('No sort'), + DIFF_SORT_VALUE => t('Sort'), + DIFF_SORT_CUSTOM => t('Sort if free tagging field'), + ), + '#default_value' => $settings['sort'], + ); + return $options_form; +} diff --git a/profiles/wcm_base/modules/contrib/diff/includes/text.inc b/profiles/wcm_base/modules/contrib/diff/includes/text.inc new file mode 100644 index 00000000..b27e55ff --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/includes/text.inc @@ -0,0 +1,113 @@ +<?php + +/** + * @file + * Provide diff field functions for the Text module. + */ + +/** + * Diff field callback for parsing text field comparative values. + */ +function text_field_diff_view($items, $context) { + $field = $context['field']; + $instance = $context['instance']; + $settings = $context['settings']; + + $diff_items = array(); + foreach ($items as $delta => $item) { + $diff_items[$delta] = array(); + + // Compute the format for appending to the label. + $format_text = ''; + if ($instance['settings']['text_processing'] && $settings['compare_format']) { + $format_id = empty($item['format']) ? filter_fallback_format() : $item['format']; + if ($format = filter_format_load($format_id)) { + $format_text = $format->name; + } + else { + $format_text = t('Missing format !format', array('!format' => $format_id)); + } + } + + // Compare the summary fields. + $summary = $field['type'] == 'text_with_summary' && $settings['compare_summary']; + if ($summary) { + // Allow users to optionally clean system specific characters. + if (empty($item['summary'])) { + $diff_items[$delta][] = t('Summary field is empty.'); + } + else { + if ($format_text) { + $diff_items[$delta][] = t('Summary (!text_format):', array('!text_format' => $format_text)); + } + else { + $diff_items[$delta][] = t('Summary:'); + } + $diff_items[$delta][] = diff_normalise_text($item['summary']); + } + } + + // Only show label if field has summary displayed. + if ($summary) { + if ($format_text) { + $diff_items[$delta][] = t('Content (!text_format):', array('!text_format' => $format_text)); + } + else { + $diff_items[$delta][] = t('Content:'); + } + } + + // Allow users to optionally clean system specific characters. + $diff_items[$delta][] = diff_normalise_text($item['value']); + + // If no summary, append the format selection to the bottom of the screen. + // This prevents adding the "Content (format)" label. + if ($format_text && !$summary) { + $diff_items[$delta][] = t('Text format: !text_format', array('!text_format' => $format_text)); + } + + $diff_items[$delta] = $diff_items[$delta]; + } + return $diff_items; +} + +/** + * Provide default field comparison options. + */ +function text_field_diff_default_options($field_type) { + // Overrides the global 'markdown' setting which does not escape HTML. + $settings = array( + 'compare_format' => 0, + 'markdown' => 'drupal_html_to_text', + 'line_counter' => '', + ); + if ($field_type == 'text_with_summary') { + $settings += array( + 'compare_summary' => 0, + ); + } + + return $settings; +} + +/** + * Provide a form for setting the field comparison options. + */ +function text_field_diff_options_form($field_type, $settings) { + $options_form = array(); + $options_form['compare_format'] = array( + '#type' => 'checkbox', + '#title' => t('Compare format'), + '#default_value' => $settings['compare_format'], + '#description' => t('This is only used if the "Text processing" instance settings are set to <em>Filtered text (user selects text format)</em>.'), + ); + if ($field_type == 'text_with_summary') { + $options_form['compare_summary'] = array( + '#type' => 'checkbox', + '#title' => t('Compare summary separately'), + '#default_value' => $settings['compare_summary'], + '#description' => t('This is only used if the "Summary input" option is checked in the instance settings.'), + ); + } + return $options_form; +} diff --git a/profiles/wcm_base/modules/contrib/diff/js/diff.js b/profiles/wcm_base/modules/contrib/diff/js/diff.js new file mode 100644 index 00000000..2c873e9f --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/js/diff.js @@ -0,0 +1,58 @@ +(function ($) { + +Drupal.behaviors.diffRevisions = { + attach: function (context, settings) { + var $rows = $('table.diff-revisions tbody tr'); + function updateDiffRadios() { + var newTd = false; + var oldTd = false; + if (!$rows.length) { + return true; + } + $rows.removeClass('selected').each(function() { + var $row = $(this); + $row.removeClass('selected'); + var $inputs = $row.find('input[type="radio"]'); + var $oldRadio = $inputs.filter('[name="old"]').eq(0); + var $newRadio = $inputs.filter('[name="new"]').eq(0); + if (!$oldRadio.length || !$newRadio.length) { + return true; + } + if ($oldRadio.attr('checked')) { + oldTd = true; + $row.addClass('selected'); + $oldRadio.css('visibility', 'visible'); + $newRadio.css('visibility', 'hidden'); + } else if ($newRadio.attr('checked')) { + newTd = true; + $row.addClass('selected'); + $oldRadio.css('visibility', 'hidden'); + $newRadio.css('visibility', 'visible'); + } else { + if (Drupal.settings.diffRevisionRadios == 'linear') { + if (newTd && oldTd) { + $oldRadio.css('visibility', 'visible'); + $newRadio.css('visibility', 'hidden'); + } else if (newTd) { + $newRadio.css('visibility', 'visible'); + $oldRadio.css('visibility', 'visible'); + } else { + $newRadio.css('visibility', 'visible'); + $oldRadio.css('visibility', 'hidden'); + } + } else { + $newRadio.css('visibility', 'visible'); + $oldRadio.css('visibility', 'visible'); + } + } + }); + return true; + } + if (Drupal.settings.diffRevisionRadios) { + $rows.find('input[name="new"], input[name="old"]').click(updateDiffRadios); + updateDiffRadios(); + } + } +}; + +})(jQuery); diff --git a/profiles/wcm_base/modules/contrib/diff/readme.txt b/profiles/wcm_base/modules/contrib/diff/readme.txt new file mode 100644 index 00000000..f82db821 --- /dev/null +++ b/profiles/wcm_base/modules/contrib/diff/readme.txt @@ -0,0 +1,136 @@ +Diff module - http://drupal.org/project/diff +============================================ + +Diff enhances usage of node revisions by adding the following features: + +- Diff between node revisions on the 'Revisions' tab to view all the changes + between any two revisions of a node. +- Highlight changes inline while viewing a node to quickly see color-coded + additions, changes, and deletions. +- Preview changes as a diff before updating a node. + +It is also an API to compare any entities although this functionality is not +exposed by the core Diff module. + +REQUIREMENTS +------------ +Drupal 7.x + +INSTALLATION +------------ +1. Place the Diff module into your modules directory. + This is normally the "sites/all/modules" directory. + +2. Go to admin/build/modules. Enable the module. + The Diff modules is found in the Other section. + +Read more about installing modules at http://drupal.org/node/70151 + +See the configuration section below. + +UPGRADING +--------- +Any updates should be automatic. Just remember to run update.php! + +CONFIGURATION +------------- + +Unlike the earlier version, the module now has a lot of configurable settings. + +Global settings can be found under Configuration > Content > Diff + +i.e. http://www.example.com/admin/config/content/diff + +Entity specific settings would be listed under the entities settings. This +module only handles Node revisioning functionality, and these are detailed +below. + +1) Node revisioning settings + +Diff needs to be configured to be used with specific node types on your site. +To enable any of Diff's options on a content type's settings page. + +e.g. http://www.example.com/admin/structure/types/manage/page + + a) Diff options + + Under "Compare revisions", enable the settings that you want; + + i) "Show View changes button on node edit form" adds a new "Preview" like + submit button to node editing pages. This shows a diff preview. + + ii) "Enable the Revisions page for this content type" adds the revisioning + tab to content. This allows users to compare between various revisions + that they have access to. + + iii) "Standard comparison preview" option allows you to control how the most + current revision is show on the revision comparision page. + + b) Publishing options + + It is strongly advised that you also enable the automatic creation of + revisions on any content types you want to use this with. If you do not do + this, chances are there will be limited revisioning information available to + compare. + + Under "Publishing options", enable "Create new revision". + +2) Field revisioning settings + + Global settings per field type can be found here: + + http://www.example.com/admin/config/content/diff/fields + + "Show field title" toggles field title visibility on the comparison page. + + "Markdown callback" is the callback used to render the field when viewing the + page in the "Marked down" page view. + + "Line counter" is an optional. This shows the approximate line number where + the change occurred. This is an approximate counter only. + + Other fields add additional settings here. + +3) Entity revisioning settings + + Global configurable settings limited to node entities. + + a) Show entity label header + + This provides a field like title for the entity label field. + + i.e. For nodes, this provides a header for the node's title. + + b) Treat diff pages as administrative + + By default, the revisioning pages are administrative, i.e. they will use the + administration theme. You can block this by unchecking this option. + +4) Global settings + +A small number of new features have been added to the 7.x-3.x branch, these +include the ability to change the leading and trailing lines in the comparison, +a new CSS theme for the diff pages, new JScript options for the revisioning +selection form and options to help prevent cross operating systems in relation +to line endings. + +http://www.example.com/admin/config/content/diff + +Technical +--------- +- Diff compares the raw data, not the filtered output, making it easier to see +changes to HTML entities, etc. +- The diff engine itself is a GPL'ed php diff engine from phpwiki. + +API +--- +See diff.api.php + +Maintainers +----------- +- realityloop (Brian Gilbert) +- Alan D. (Alan Davison) +- dww (Derek Wright) +- moshe (Moshe Weitzman) +- rötzi (Julian) +- yhahn (Young Hahn) diff --git a/profiles/wcm_base/modules/contrib/draggableviews/draggableviews.info b/profiles/wcm_base/modules/contrib/draggableviews/draggableviews.info index ce149140..b7bc7109 100644 --- a/profiles/wcm_base/modules/contrib/draggableviews/draggableviews.info +++ b/profiles/wcm_base/modules/contrib/draggableviews/draggableviews.info @@ -19,9 +19,9 @@ dependencies[] = ctools dependencies[] = entity dependencies[] = views -; Information added by Drupal.org packaging script on 2015-07-11 -version = "7.x-2.1+9-dev" +; Information added by Drupal.org packaging script on 2016-09-07 +version = "7.x-2.1+10-dev" core = "7.x" project = "draggableviews" -datestamp = "1436650744" +datestamp = "1473261841" diff --git a/profiles/wcm_base/modules/contrib/draggableviews/draggableviews.module b/profiles/wcm_base/modules/contrib/draggableviews/draggableviews.module index 22aeeba3..a9fcab40 100644 --- a/profiles/wcm_base/modules/contrib/draggableviews/draggableviews.module +++ b/profiles/wcm_base/modules/contrib/draggableviews/draggableviews.module @@ -591,3 +591,20 @@ function _draggableviews_get_views_options($view = NULL) { } return $options; } + +/** + * Implements hook_node_delete(). + */ +function draggableviews_node_delete($node) { + // Code to check if entry present in draggableviews_structure table. + $nid = $node->nid; + $query = db_select('draggableviews_structure', 'ds') + ->condition('entity_id', $nid) + ->fields('ds', array('view_name')); + + $result = $query->execute()->rowCount(); + // Code to remove entries from draggableviews_structure table. + if ($result > 0) { + db_delete('draggableviews_structure')->condition('entity_id', $nid)->execute(); + } +} diff --git a/profiles/wcm_base/modules/contrib/draggableviews/draggableviews_book/draggableviews_book.info b/profiles/wcm_base/modules/contrib/draggableviews/draggableviews_book/draggableviews_book.info index 473802a2..f7a97740 100644 --- a/profiles/wcm_base/modules/contrib/draggableviews/draggableviews_book/draggableviews_book.info +++ b/profiles/wcm_base/modules/contrib/draggableviews/draggableviews_book/draggableviews_book.info @@ -7,9 +7,9 @@ files[] = draggableviews_book_views_handler_argument.inc dependencies[] = draggableviews dependencies[] = book -; Information added by Drupal.org packaging script on 2015-07-11 -version = "7.x-2.1+9-dev" +; Information added by Drupal.org packaging script on 2016-09-07 +version = "7.x-2.1+10-dev" core = "7.x" project = "draggableviews" -datestamp = "1436650744" +datestamp = "1473261841" diff --git a/profiles/wcm_base/modules/contrib/draggableviews/test/draggableviews_test/draggableviews_test.info b/profiles/wcm_base/modules/contrib/draggableviews/test/draggableviews_test/draggableviews_test.info index caac68d6..4ecd4576 100644 --- a/profiles/wcm_base/modules/contrib/draggableviews/test/draggableviews_test/draggableviews_test.info +++ b/profiles/wcm_base/modules/contrib/draggableviews/test/draggableviews_test/draggableviews_test.info @@ -4,9 +4,9 @@ dependencies[] = draggableviews package = Views core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2015-07-11 -version = "7.x-2.1+9-dev" +; Information added by Drupal.org packaging script on 2016-09-07 +version = "7.x-2.1+10-dev" core = "7.x" project = "draggableviews" -datestamp = "1436650744" +datestamp = "1473261841" diff --git a/profiles/wcm_base/modules/custom/ocio_wysiwyg/ocio_wysiwyg.features.wysiwyg.inc b/profiles/wcm_base/modules/custom/ocio_wysiwyg/ocio_wysiwyg.features.wysiwyg.inc index f8d544b2..79902ef8 100644 --- a/profiles/wcm_base/modules/custom/ocio_wysiwyg/ocio_wysiwyg.features.wysiwyg.inc +++ b/profiles/wcm_base/modules/custom/ocio_wysiwyg/ocio_wysiwyg.features.wysiwyg.inc @@ -52,6 +52,9 @@ function ocio_wysiwyg_wysiwyg_default_profiles() { 'accordion' => array( 'accordion' => 1, ), + 'menuMods' => array( + 'tabs' => 1, + ), 'tabs' => array( 'tabs' => 1, ), @@ -70,10 +73,10 @@ function ocio_wysiwyg_wysiwyg_default_profiles() { 'acf_allowed_content' => '', 'css_setting' => 'none', 'css_path' => '', - 'stylesSet' => 'Tagline=div.tagline -Subhead=p.subhead -Intro Text=p.intro-text -Button=a.button + 'stylesSet' => 'Tagline=div.tagline +Subhead=p.subhead +Intro Text=p.intro-text +Button=a.button Pull Quote=blockquote.pull-quote', 'block_formats' => 'p,h2,h3,h4', 'advanced__active_tab' => 'edit-basic', diff --git a/profiles/wcm_base/modules/custom/ocio_wysiwyg/ocio_wysiwyg.module b/profiles/wcm_base/modules/custom/ocio_wysiwyg/ocio_wysiwyg.module index 6bc0ef2b..f6cb7d57 100644 --- a/profiles/wcm_base/modules/custom/ocio_wysiwyg/ocio_wysiwyg.module +++ b/profiles/wcm_base/modules/custom/ocio_wysiwyg/ocio_wysiwyg.module @@ -24,7 +24,7 @@ function ocio_wysiwyg_wysiwyg_editor_settings_alter(&$settings, $context) { $settings['contentsCss'][] = $module_path . '/replace/ui/themes/base/minified/jquery.ui.tabs.min.css'; } - $settings['removeDialogTabs'] = 'table:advanced'; + $settings['removeDialogTabs'] = 'tableProperties:advanced;'; $settings['justifyClasses'] = array( 'align-left', @@ -63,6 +63,13 @@ function ocio_wysiwyg_wysiwyg_plugin($editor, $version) { ), 'load' => TRUE, ), + 'menuMods' => array( + 'path' => drupal_get_path('module', 'ocio_wysiwyg') . '/plugins/menuMods', + 'buttons' => array( + 'menuMods' => t('MenuMods'), + ), + 'load' => TRUE, + ), ); break; } diff --git a/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/icon-tabs.png b/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/icon-tabs.png deleted file mode 100644 index 313444964140432f3389370180dd18b1118d819f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 344 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZKG?d}4kf#9d}?s_1_ zS>O>_%)r1c1j3A$?$-SQ3hwcAaSX9Iy>#+MuEPdAF6WC_mG(a}4X#)Fcl)2OfeT;U zsZtJEDe+lL*tgpxD*nuQ;LpnNXL;k3IgXzWUpA3VvP}2L=1p8)8q2@&n$(ghmwLDA zoK_6;YCQA#j_A1!(QCJAuh2SHn3B!QkdP*?)6$SA@!*|<*Glik+4HQ+b(XpWUbVaJ zTll<hrIw4!y8VoTC$?K#tcub;a#!EHpgd;&|GjQKA3r^mP)<lY@@=8t?K2#c$|v>f f@BII%`N>~a1^N4~$2bfuL7wz<^>bP0l+XkKNMU=t diff --git a/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/menuMods/plugin.js b/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/menuMods/plugin.js new file mode 100644 index 00000000..3332a0c3 --- /dev/null +++ b/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/menuMods/plugin.js @@ -0,0 +1,18 @@ +(function($){ + CKEDITOR.plugins.add('menuMods'); + + CKEDITOR.on('dialogDefinition', function(ev) { + if (ev.data.name == 'cellProperties') { + var infoTab = ev.data.definition.getContents('info'); + infoTab.remove('width'); + infoTab.remove('widthType'); + infoTab.remove('height'); + infoTab.remove('htmlHeightType'); + infoTab.remove('borderColor'); + infoTab.remove('bgColor'); + infoTab.remove('borderColorChoose'); + infoTab.remove('bgColorChoose'); + } + }); + +})(jQuery); diff --git a/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/tabs/plugin.js b/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/tabs/plugin.js index c812e83f..6d50ea40 100644 --- a/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/tabs/plugin.js +++ b/profiles/wcm_base/modules/custom/ocio_wysiwyg/plugins/tabs/plugin.js @@ -43,4 +43,5 @@ CKEDITOR.plugins.add('tabs', { }); } }); + })(jQuery); diff --git a/profiles/wcm_base/modules/custom/wcm_panels_settings/wcm_panels_settings.module b/profiles/wcm_base/modules/custom/wcm_panels_settings/wcm_panels_settings.module index 3f03e405..07d7e1b0 100644 --- a/profiles/wcm_base/modules/custom/wcm_panels_settings/wcm_panels_settings.module +++ b/profiles/wcm_base/modules/custom/wcm_panels_settings/wcm_panels_settings.module @@ -237,3 +237,16 @@ function wcm_panels_settings_linkchecker_node_links_alter(&$links, $node, $conte function wcm_panels_settings_form_panels_ipe_edit_control_form_alter(&$form, &$form_state) { $form['options']['revision']['#default_value'] = FALSE; } + +/* + * Implements hook_panels_display_save(). + * + * Clear page cache when saving panelized node. + */ +function wcm_panels_settings_panels_display_save($display) { + if (isset($display->context['panelizer']) && $display->context['panelizer']->plugin == 'entity:node') { + $path = $display->context['panelizer']->data->path['source']; + $url = url($path, array('absolute' => TRUE)); + cache_clear_all($url, 'cache_page'); + } +} diff --git a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.features.inc b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.features.inc index 90be2ac2..6291b13b 100644 --- a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.features.inc +++ b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.features.inc @@ -4,6 +4,15 @@ * wcm_workbench.features.inc */ +/** + * Implements hook_ctools_plugin_api(). + */ +function wcm_workbench_ctools_plugin_api($module = NULL, $api = NULL) { + if ($module == "strongarm" && $api == "strongarm") { + return array("version" => "1"); + } +} + /** * Implements hook_views_api(). */ diff --git a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.info b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.info index 7ce79e0f..49d21364 100644 --- a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.info +++ b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.info @@ -5,11 +5,14 @@ package = WCM Configuration version = 7.x-1.0 project = wcm_workbench dependencies[] = ctools +dependencies[] = diff dependencies[] = features +dependencies[] = strongarm dependencies[] = views dependencies[] = workbench dependencies[] = workbench_media dependencies[] = workbench_moderation +features[ctools][] = strongarm:strongarm:1 features[ctools][] = views:views_default:3.0 features[features_api][] = api:2 features[features_override_items][] = views_view.workbench_edited @@ -33,6 +36,11 @@ features[features_overrides][] = views_view.workbench_recent_content.display|pag features[features_overrides][] = views_view.workbench_recent_content.display|page_1|display_options|menu|title features[features_overrides][] = views_view.workbench_recent_content.display|page_1|display_options|path features[features_overrides][] = views_view.workbench_recent_content.display|page_1|display_options|title +features[variable][] = diff_context_lines_leading +features[variable][] = diff_context_lines_trailing +features[variable][] = diff_default_state_node +features[variable][] = diff_radio_behavior +features[variable][] = diff_theme features[views_view][] = files features[workbench_moderation_states][] = draft features[workbench_moderation_states][] = needs_review diff --git a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.make b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.make index f7fad68d..3e87074d 100644 --- a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.make +++ b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.make @@ -29,3 +29,6 @@ projects[workbench_moderation][patch][1492118] = http://drupal.org/files/issues/ projects[workbench_moderation][patch][2485713] = http://drupal.org/files/issues/workbench-moderation-ajax-block-2485713-6.patch projects[workbench_moderation][patch][2462453] = http://drupal.org/files/issues/workbench_moderation-iib-var-2462453-1.patch projects[workbench_moderation][patch][2360973] = http://drupal.org/files/issues/workbench_moderation-install-warnings-2360973-3.patch + +projects[diff][version] = 3.2 +projects[diff][subdir] = contrib diff --git a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.module b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.module index 7082266a..a8611c2d 100644 --- a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.module +++ b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.module @@ -47,3 +47,39 @@ function wcm_workbench_form_node_revision_delete_confirm_alter(&$form, &$form_st $form['description']['#prefix'] = t('You are about to delete the revision of %title dated @time.', array('%title' => $form['#node_revision']->title, '@time' => format_date($form['#node_revision']->revision_timestamp))); } +/* + * Implements hook_node_view(). + * + * Add links to workbench block to view changes between revisions. + */ +function wcm_workbench_node_view($node, $view_mode) { + if ($view_mode = 'full') { + $links = array(); + + $url = 'node/'. $node->nid . '/moderation/diff/view/'; + + if(isset($node->workbench_moderation['published'])) { + $published = $node->workbench_moderation['published']->vid; + if ($node->vid != $published) { + $links[] = l('Published revision', $url . $published . '/' . $node->vid); + } + } + + if(isset($node->workbench_moderation['current']) ) { + $current = $node->workbench_moderation['current']->vid; + if ($node->vid != $current) { + $links[] = l('Latest draft', $url . $node->vid . '/' . $current); + } + } + + if (!empty($links)) { + $messages = array( + 'label' => t('Compare to'), + 'message' => implode($links, ' | ') + ); + workbench_moderation_messages('view', $node); + workbench_moderation_set_message(array($messages)); + } + } +} + diff --git a/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.strongarm.inc b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.strongarm.inc new file mode 100644 index 00000000..4e27b2ec --- /dev/null +++ b/profiles/wcm_base/modules/custom/wcm_workbench/wcm_workbench.strongarm.inc @@ -0,0 +1,49 @@ +<?php +/** + * @file + * wcm_workbench.strongarm.inc + */ + +/** + * Implements hook_strongarm(). + */ +function wcm_workbench_strongarm() { + $export = array(); + + $strongarm = new stdClass(); + $strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */ + $strongarm->api_version = 1; + $strongarm->name = 'diff_context_lines_leading'; + $strongarm->value = '2'; + $export['diff_context_lines_leading'] = $strongarm; + + $strongarm = new stdClass(); + $strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */ + $strongarm->api_version = 1; + $strongarm->name = 'diff_context_lines_trailing'; + $strongarm->value = '2'; + $export['diff_context_lines_trailing'] = $strongarm; + + $strongarm = new stdClass(); + $strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */ + $strongarm->api_version = 1; + $strongarm->name = 'diff_default_state_node'; + $strongarm->value = 'raw_plain'; + $export['diff_default_state_node'] = $strongarm; + + $strongarm = new stdClass(); + $strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */ + $strongarm->api_version = 1; + $strongarm->name = 'diff_radio_behavior'; + $strongarm->value = 'simple'; + $export['diff_radio_behavior'] = $strongarm; + + $strongarm = new stdClass(); + $strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */ + $strongarm->api_version = 1; + $strongarm->name = 'diff_theme'; + $strongarm->value = 'default'; + $export['diff_theme'] = $strongarm; + + return $export; +} diff --git a/profiles/wcm_base/themes/ocio_omega_base/css/layouts/ocio-default/ocio-default.layout.css b/profiles/wcm_base/themes/ocio_omega_base/css/layouts/ocio-default/ocio-default.layout.css index 69e69116..00d07f5d 100644 --- a/profiles/wcm_base/themes/ocio_omega_base/css/layouts/ocio-default/ocio-default.layout.css +++ b/profiles/wcm_base/themes/ocio_omega_base/css/layouts/ocio-default/ocio-default.layout.css @@ -247,31 +247,6 @@ textarea { resize: none; } -.webform-component label { - text-transform: uppercase; - font-weight: 600; - font-size: 14px; -} -.webform-component .description { - margin-bottom: 30px; -} - -.webform-component-fieldset .webform-component label { - text-transform: uppercase; - font-weight: 400; - font-size: 13px; -} - -.webform-component-fieldset, -.webform-component-file, -.webform-component-grid { - margin-bottom: 40px; -} - -.webform-component-file #edit-submitted-file-upload { - max-width: 240px; -} - @media (max-width: 47.5em) { .l-main input, .l-main select, .l-main textarea { width: 100%; diff --git a/profiles/wcm_base/themes/ocio_omega_base/css/layouts/ocio-default/ocio-default.layout.no-query.css b/profiles/wcm_base/themes/ocio_omega_base/css/layouts/ocio-default/ocio-default.layout.no-query.css index 991767ac..5c5d799b 100644 --- a/profiles/wcm_base/themes/ocio_omega_base/css/layouts/ocio-default/ocio-default.layout.no-query.css +++ b/profiles/wcm_base/themes/ocio_omega_base/css/layouts/ocio-default/ocio-default.layout.no-query.css @@ -247,31 +247,6 @@ textarea { resize: none; } -.webform-component label { - text-transform: uppercase; - font-weight: 600; - font-size: 14px; -} -.webform-component .description { - margin-bottom: 30px; -} - -.webform-component-fieldset .webform-component label { - text-transform: uppercase; - font-weight: 400; - font-size: 13px; -} - -.webform-component-fieldset, -.webform-component-file, -.webform-component-grid { - margin-bottom: 40px; -} - -.webform-component-file #edit-submitted-file-upload { - max-width: 240px; -} - .l-main input, .l-main select, .l-main textarea { width: 100%; } diff --git a/profiles/wcm_base/themes/ocio_omega_base/css/ocio-omega-base.no-query.css b/profiles/wcm_base/themes/ocio_omega_base/css/ocio-omega-base.no-query.css index 2cdd13e4..af67a913 100644 --- a/profiles/wcm_base/themes/ocio_omega_base/css/ocio-omega-base.no-query.css +++ b/profiles/wcm_base/themes/ocio_omega_base/css/ocio-omega-base.no-query.css @@ -76,7 +76,7 @@ html body .button, #edit-submit--3, .webform-submit, .webform-previous, -.button-primary, .page-user-login .login-box.osu a, .node-type-webform #edit-submitted-file-upload-button { +.button-primary, .page-user-login .login-box.osu a, .node-type-web-form #edit-submitted-file-upload-button { font-size: 14px; padding: 0.6em 1.3em 0.5em 1.3em; display: inline-block; @@ -108,7 +108,7 @@ html body .button:hover, #edit-submit--3:hover, .webform-submit:hover, .webform-previous:hover, -.button-primary:hover, .page-user-login .login-box.osu a:hover, .node-type-webform #edit-submitted-file-upload-button:hover { +.button-primary:hover, .page-user-login .login-box.osu a:hover, .node-type-web-form #edit-submitted-file-upload-button:hover { text-decoration: none; } .red-button:hover, input[type=button]:hover, @@ -120,7 +120,7 @@ html body .button:hover, #edit-submit--3:hover, .webform-submit:hover, .webform-previous:hover, -.button-primary:hover, .page-user-login .login-box.osu a:hover, .node-type-webform #edit-submitted-file-upload-button:hover { +.button-primary:hover, .page-user-login .login-box.osu a:hover, .node-type-web-form #edit-submitted-file-upload-button:hover { background-color: #a20000; } .red-button:active, input[type=button]:active, @@ -132,7 +132,7 @@ html body .button:active, #edit-submit--3:active, .webform-submit:active, .webform-previous:active, -.button-primary:active, .page-user-login .login-box.osu a:active, .node-type-webform #edit-submitted-file-upload-button:active { +.button-primary:active, .page-user-login .login-box.osu a:active, .node-type-web-form #edit-submitted-file-upload-button:active { background-color: #920000; } .red-button.disabled, input.disabled[type=button], @@ -144,7 +144,7 @@ html body .disabled.button, .disabled#edit-submit--3, .disabled.webform-submit, .disabled.webform-previous, -.disabled.button-primary, .page-user-login .login-box.osu a.disabled, .node-type-webform .disabled#edit-submitted-file-upload-button, .red-button[disabled], input[disabled][type=button], +.disabled.button-primary, .page-user-login .login-box.osu a.disabled, .node-type-web-form .disabled#edit-submitted-file-upload-button, .red-button[disabled], input[disabled][type=button], html body [disabled].button, [disabled].form-submit, [disabled]#edit-preview, @@ -153,7 +153,7 @@ html body [disabled].button, [disabled]#edit-submit--3, [disabled].webform-submit, [disabled].webform-previous, -[disabled].button-primary, .page-user-login .login-box.osu a[disabled], .node-type-webform [disabled]#edit-submitted-file-upload-button { +[disabled].button-primary, .page-user-login .login-box.osu a[disabled], .node-type-web-form [disabled]#edit-submitted-file-upload-button { filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=60); opacity: 0.6; background: false; @@ -171,7 +171,7 @@ html body .button::-moz-focus-inner, #edit-submit--3::-moz-focus-inner, .webform-submit::-moz-focus-inner, .webform-previous::-moz-focus-inner, -.button-primary::-moz-focus-inner, .page-user-login .login-box.osu a::-moz-focus-inner, .node-type-webform #edit-submitted-file-upload-button::-moz-focus-inner { +.button-primary::-moz-focus-inner, .page-user-login .login-box.osu a::-moz-focus-inner, .node-type-web-form #edit-submitted-file-upload-button::-moz-focus-inner { padding: 0 !important; margin: -1px !important; } @@ -243,31 +243,6 @@ textarea { resize: none; } -.webform-component label { - text-transform: uppercase; - font-weight: 600; - font-size: 14px; -} -.webform-component .description { - margin-bottom: 30px; -} - -.webform-component-fieldset .webform-component label { - text-transform: uppercase; - font-weight: 400; - font-size: 13px; -} - -.webform-component-fieldset, -.webform-component-file, -.webform-component-grid { - margin-bottom: 40px; -} - -.webform-component-file #edit-submitted-file-upload { - max-width: 240px; -} - .l-main input, .l-main select, .l-main textarea { width: 100%; } @@ -2478,18 +2453,46 @@ p.search-result__snippet { border: 1px solid #8c8c8c; } -.node-type-webform .webform-component-fieldset { - margin: 40px 0 20px 0; +.node-type-web-form .webform-component-fieldset { + margin: 30px 0 20px 0; padding: 20px 1.5em; } -.node-type-webform .webform-component-fieldset legend { +.node-type-web-form .webform-component-fieldset legend { text-transform: uppercase; font-weight: 600; padding: 0 0.375em; } -.node-type-webform #edit-submitted-file-ajax-wrapper { +.node-type-web-form #edit-submitted-file-ajax-wrapper { padding: 20px 0; } +.node-type-web-form .webform-component > label { + text-transform: uppercase; + font-weight: 600; + margin-bottom: 0.4em; +} +.node-type-web-form .webform-component label.option { + font-size: 15px; + margin-left: 4px; +} +.node-type-web-form .webform-component .description, .node-type-web-form .webform-component.form-item, .node-type-web-form .webform-component.form-actions { + margin-bottom: 30px; +} +.node-type-web-form .webform-component-fieldset .webform-component > label { + text-transform: uppercase; + font-size: 15px; + color: #666666; +} +.node-type-web-form .webform-component-fieldset .webform-component.form-item:last-child { + margin-bottom: 0; +} +.node-type-web-form .webform-component-fieldset, +.node-type-web-form .webform-component-file, +.node-type-web-form .webform-component-grid { + margin-bottom: 30px; +} +.node-type-web-form .webform-component-file #edit-submitted-file-upload { + max-width: 240px; +} .webform-client-form { padding-top: 2em; diff --git a/profiles/wcm_base/themes/ocio_omega_base/css/ocio-omega-base.styles.css b/profiles/wcm_base/themes/ocio_omega_base/css/ocio-omega-base.styles.css index 99db0135..ad36bd4e 100644 --- a/profiles/wcm_base/themes/ocio_omega_base/css/ocio-omega-base.styles.css +++ b/profiles/wcm_base/themes/ocio_omega_base/css/ocio-omega-base.styles.css @@ -76,7 +76,7 @@ html body .button, #edit-submit--3, .webform-submit, .webform-previous, -.button-primary, .page-user-login .login-box.osu a, .node-type-webform #edit-submitted-file-upload-button { +.button-primary, .page-user-login .login-box.osu a, .node-type-web-form #edit-submitted-file-upload-button { font-size: 14px; padding: 0.6em 1.3em 0.5em 1.3em; display: inline-block; @@ -108,7 +108,7 @@ html body .button:hover, #edit-submit--3:hover, .webform-submit:hover, .webform-previous:hover, -.button-primary:hover, .page-user-login .login-box.osu a:hover, .node-type-webform #edit-submitted-file-upload-button:hover { +.button-primary:hover, .page-user-login .login-box.osu a:hover, .node-type-web-form #edit-submitted-file-upload-button:hover { text-decoration: none; } .red-button:hover, input[type=button]:hover, @@ -120,7 +120,7 @@ html body .button:hover, #edit-submit--3:hover, .webform-submit:hover, .webform-previous:hover, -.button-primary:hover, .page-user-login .login-box.osu a:hover, .node-type-webform #edit-submitted-file-upload-button:hover { +.button-primary:hover, .page-user-login .login-box.osu a:hover, .node-type-web-form #edit-submitted-file-upload-button:hover { background-color: #a20000; } .red-button:active, input[type=button]:active, @@ -132,7 +132,7 @@ html body .button:active, #edit-submit--3:active, .webform-submit:active, .webform-previous:active, -.button-primary:active, .page-user-login .login-box.osu a:active, .node-type-webform #edit-submitted-file-upload-button:active { +.button-primary:active, .page-user-login .login-box.osu a:active, .node-type-web-form #edit-submitted-file-upload-button:active { background-color: #920000; } .red-button.disabled, input.disabled[type=button], @@ -144,7 +144,7 @@ html body .disabled.button, .disabled#edit-submit--3, .disabled.webform-submit, .disabled.webform-previous, -.disabled.button-primary, .page-user-login .login-box.osu a.disabled, .node-type-webform .disabled#edit-submitted-file-upload-button, .red-button[disabled], input[disabled][type=button], +.disabled.button-primary, .page-user-login .login-box.osu a.disabled, .node-type-web-form .disabled#edit-submitted-file-upload-button, .red-button[disabled], input[disabled][type=button], html body [disabled].button, [disabled].form-submit, [disabled]#edit-preview, @@ -153,7 +153,7 @@ html body [disabled].button, [disabled]#edit-submit--3, [disabled].webform-submit, [disabled].webform-previous, -[disabled].button-primary, .page-user-login .login-box.osu a[disabled], .node-type-webform [disabled]#edit-submitted-file-upload-button { +[disabled].button-primary, .page-user-login .login-box.osu a[disabled], .node-type-web-form [disabled]#edit-submitted-file-upload-button { filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=60); opacity: 0.6; background: false; @@ -171,7 +171,7 @@ html body .button::-moz-focus-inner, #edit-submit--3::-moz-focus-inner, .webform-submit::-moz-focus-inner, .webform-previous::-moz-focus-inner, -.button-primary::-moz-focus-inner, .page-user-login .login-box.osu a::-moz-focus-inner, .node-type-webform #edit-submitted-file-upload-button::-moz-focus-inner { +.button-primary::-moz-focus-inner, .page-user-login .login-box.osu a::-moz-focus-inner, .node-type-web-form #edit-submitted-file-upload-button::-moz-focus-inner { padding: 0 !important; margin: -1px !important; } @@ -243,31 +243,6 @@ textarea { resize: none; } -.webform-component label { - text-transform: uppercase; - font-weight: 600; - font-size: 14px; -} -.webform-component .description { - margin-bottom: 30px; -} - -.webform-component-fieldset .webform-component label { - text-transform: uppercase; - font-weight: 400; - font-size: 13px; -} - -.webform-component-fieldset, -.webform-component-file, -.webform-component-grid { - margin-bottom: 40px; -} - -.webform-component-file #edit-submitted-file-upload { - max-width: 240px; -} - @media (max-width: 47.5em) { .l-main input, .l-main select, .l-main textarea { width: 100%; @@ -2510,18 +2485,46 @@ p.search-result__snippet { border: 1px solid #8c8c8c; } -.node-type-webform .webform-component-fieldset { - margin: 40px 0 20px 0; +.node-type-web-form .webform-component-fieldset { + margin: 30px 0 20px 0; padding: 20px 1.5em; } -.node-type-webform .webform-component-fieldset legend { +.node-type-web-form .webform-component-fieldset legend { text-transform: uppercase; font-weight: 600; padding: 0 0.375em; } -.node-type-webform #edit-submitted-file-ajax-wrapper { +.node-type-web-form #edit-submitted-file-ajax-wrapper { padding: 20px 0; } +.node-type-web-form .webform-component > label { + text-transform: uppercase; + font-weight: 600; + margin-bottom: 0.4em; +} +.node-type-web-form .webform-component label.option { + font-size: 15px; + margin-left: 4px; +} +.node-type-web-form .webform-component .description, .node-type-web-form .webform-component.form-item, .node-type-web-form .webform-component.form-actions { + margin-bottom: 30px; +} +.node-type-web-form .webform-component-fieldset .webform-component > label { + text-transform: uppercase; + font-size: 15px; + color: #666666; +} +.node-type-web-form .webform-component-fieldset .webform-component.form-item:last-child { + margin-bottom: 0; +} +.node-type-web-form .webform-component-fieldset, +.node-type-web-form .webform-component-file, +.node-type-web-form .webform-component-grid { + margin-bottom: 30px; +} +.node-type-web-form .webform-component-file #edit-submitted-file-upload { + max-width: 240px; +} .webform-client-form { padding-top: 2em; diff --git a/profiles/wcm_base/themes/ocio_omega_base/sass/base/_forms.scss b/profiles/wcm_base/themes/ocio_omega_base/sass/base/_forms.scss index 64cf94e0..146ee30a 100644 --- a/profiles/wcm_base/themes/ocio_omega_base/sass/base/_forms.scss +++ b/profiles/wcm_base/themes/ocio_omega_base/sass/base/_forms.scss @@ -10,44 +10,6 @@ textarea { resize: none; } -.webform-component { - label { - text-transform: uppercase; - font-weight: 600; - font-size: 14px; - } - - .description { - margin-bottom: 1.5 * $vert-spacing-unit; - } -} - -//label style for webcomponents nexted within fieldsets -.webform-component-fieldset { - .webform-component { - label { - text-transform: uppercase; - font-weight: 400; - font-size: 13px; - } - } -} - -//extra bottom margin for certain webfrom components -- add more as needed - -.webform-component-fieldset, -.webform-component-file, -.webform-component-grid { - margin-bottom: 2 * $vert-spacing-unit; -} - -//special style for file upload component -.webform-component-file { - #edit-submitted-file-upload { - max-width: 240px; - } -} - @include breakpoint($small, true) { .l-main { input, select, textarea { diff --git a/profiles/wcm_base/themes/ocio_omega_base/sass/components/_webform.scss b/profiles/wcm_base/themes/ocio_omega_base/sass/components/_webform.scss index 4d26475e..16cc19d1 100644 --- a/profiles/wcm_base/themes/ocio_omega_base/sass/components/_webform.scss +++ b/profiles/wcm_base/themes/ocio_omega_base/sass/components/_webform.scss @@ -1,17 +1,17 @@ -.node-type-webform { - +.node-type-web-form { + //fieldset .webform-component-fieldset { - margin: 2 * $vert-spacing-unit 0 $vert-spacing-unit 0; + margin: 1.5 * $vert-spacing-unit 0 $vert-spacing-unit 0; padding: $vert-spacing-unit $horz-spacing-unit; - + legend { text-transform: uppercase; font-weight: 600; padding: 0 0.25 * $horz-spacing-unit; } } - + //file uploads #edit-submitted-file-ajax-wrapper { padding: $vert-spacing-unit 0; @@ -19,21 +19,68 @@ #edit-submitted-file-upload-button { @extend .red-button; } -} + .webform-component { + & > label { + text-transform: uppercase; + font-weight: 600; + margin-bottom: 0.4em; + } + + label.option { + font-size: 15px; + margin-left: 4px; + } + + .description, + &.form-item, + &.form-actions { + margin-bottom: 1.5 * $vert-spacing-unit; + } + } + + //label style for webcomponents nexted within fieldsets + .webform-component-fieldset { + .webform-component { + & > label { + text-transform: uppercase; + font-size: 15px; + color: $md-gray; + } + + &.form-item:last-child { + margin-bottom: 0; + } + } + } + + //extra bottom margin for certain webfrom components -- add more as needed + .webform-component-fieldset, + .webform-component-file, + .webform-component-grid { + margin-bottom: 1.5 * $vert-spacing-unit; + } + + //special style for file upload component + .webform-component-file { + #edit-submitted-file-upload { + max-width: 240px; + } + } +} .webform-client-form { padding-top: 2em; - + .form-actions { padding-top: 2em; } - + .webform-previous { margin-right: 10px; } - + .messages { border-left: 8px solid $red; margin-bottom: 3em; @@ -42,14 +89,14 @@ margin: 0; } } - + h2.webform-page { @include font-size(2.4); margin: 1.6em 0 0.6em 0; padding-bottom: 6px; border-bottom: 3px solid $lt-gray; } - + } @@ -59,7 +106,7 @@ width: 94%; margin-top: 2em; margin-bottom: 4em; - + } .webform-progressbar-inner { background-color: $blue; @@ -98,3 +145,4 @@ font-family: $proxima; font-size: 14px; } + -- GitLab